Pages

Showing posts with label sub. Show all posts
Showing posts with label sub. Show all posts

Thursday, May 5, 2016

Android example to create grouped sub OptionsMenu


Create menu/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu
>
<item
android_id="@+id/option1"
android_orderInCategory="100"
app_showAsAction="ifRoom"
android_title="Option 1"/>
<item
android_id="@+id/option2"
android_orderInCategory="100"
app_showAsAction="never"
android_title="Option 2"/>
<item
android_id="@+id/option3"
android_orderInCategory="100"
app_showAsAction="never"
android_title="Option 3...">
<menu >
<group android_id="@+id/group3"
android_checkableBehavior="single">
<item android_id="@+id/submenu3a"
android_title="SubMenu 3A" />
<item android_id="@+id/submenu3b"
android_title="SubMenu 3B" />
</group>
</menu>

</item>
</menu>

MainActivity.java
package com.blogspot.android_er.androidoptionsmenu;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.option1:
Toast.makeText(MainActivity.this, "Option 1", Toast.LENGTH_LONG).show();
return true;
case R.id.option2:
Toast.makeText(MainActivity.this, "Option 2", Toast.LENGTH_LONG).show();
return true;
case R.id.submenu3a:
Toast.makeText(MainActivity.this, "Option 3 A", Toast.LENGTH_LONG).show();
return true;
case R.id.submenu3b:
Toast.makeText(MainActivity.this, "Option 3 B", Toast.LENGTH_LONG).show();
return true;
}
return super.onOptionsItemSelected(item);
}
}



Read More..

Saturday, April 30, 2016

Animated GIF Androidify for 3D Hologram viewer


Last post I tried to generate interactive animation using ObjectAnimator, to simulate 3D Hologram effect. This post I create Custom View to display animated GIF of Androidify, to simulate the effect.


The animated GIFs of Androidify are create using Googles Androidify App.  Then I have to edit the animated GIFs to resize it to 200x200, and change the background to black using GIMP. Then copy the files to drawable folder in Android Studio project.

Create a custom view, GifView, to handle the animated GIF. If you are looking for display animated GIF, refer "Play animated GIF using android.graphics.Movie, with Movie.decodeStream(InputStream)". In this version, I have to handle src attribute from xml, such that I can display four GifView of different source.

GifView .java
package com.blogspot.android_er.androidmirror;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;

import java.io.InputStream;

public class GifView extends View {

private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;

public GifView(Context context) {
super(context);
init(context, null);
}

public GifView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}

public GifView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}

private void init(Context context, AttributeSet attrs){
setFocusable(true);

//Handle src attribute from xml
if(attrs == null){
gifInputStream = context.getResources().openRawResource(R.drawable.androidify1b);
}else{
int src_id = attrs.getAttributeResourceValue(
"http://schemas.android.com/apk/res/android",
"src",
R.drawable.androidify1b);
gifInputStream = context.getResources().openRawResource(src_id);
}

gifMovie = Movie.decodeStream(gifInputStream);
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
}

@Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}

public int getMovieWidth(){
return movieWidth;
}

public int getMovieHeight(){
return movieHeight;
}

public long getMovieDuration(){
return movieDuration;
}

@Override
protected void onDraw(Canvas canvas) {

long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}

if (gifMovie != null) {

int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}

int relTime = (int)((now - mMovieStart) % dur);

gifMovie.setTime(relTime);

gifMovie.draw(canvas, 0, 0);
invalidate();

}

}
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout


android_layout_width="match_parent"
android_layout_height="match_parent"
android_padding="16dp"
android_background="@android:color/black"
tools_context=".MainActivity">

<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_autoLink="web"
android_text="http://android-er.blogspot.com/"
android_textStyle="bold"
android_layout_alignParentTop="true"/>

<GridLayout
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_columnCount="3"
android_layout_centerInParent="true">
<ImageView
android_layout_width="wrap_content"
android_layout_height="wrap_content"/>
<com.blogspot.android_er.androidmirror.GifView
android_id="@+id/image2"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_src="@drawable/androidify1b"
android_layout_gravity="center"/>
<ImageView
android_layout_width="wrap_content"
android_layout_height="wrap_content"/>
<com.blogspot.android_er.androidmirror.GifView
android_id="@+id/image4"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_src="@drawable/androidify2b"
android_layout_gravity="center"
android_rotation="270"/>
<ImageView
android_layout_width="20mm"
android_layout_height="20mm"/>
<com.blogspot.android_er.androidmirror.GifView
android_id="@+id/image6"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_src="@drawable/androidify3b"
android_layout_gravity="center"
android_rotation="90"/>
<ImageView
android_layout_width="wrap_content"
android_layout_height="wrap_content"/>
<com.blogspot.android_er.androidmirror.GifView
android_id="@+id/image8"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_src="@drawable/androidify4b"
android_layout_gravity="center"
android_rotation="180"/>
<ImageView
android_layout_width="wrap_content"
android_layout_height="wrap_content"/>

</GridLayout>
</RelativeLayout>


Edit AndroidManifest.xml to disable hardwareAccelerated by setting it false.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.blogspot.android_er.androidmirror" >

<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme" >
<activity android_name=".MainActivity"
android_hardwareAccelerated="false">
<intent-filter>
<action android_name="android.intent.action.MAIN" />

<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


Nothing do on MainActivity.java
package com.blogspot.android_er.androidmirror;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

}



download filesDownload the files (Android Studio Format) .

download filesDownload APK .


If you have a DIY 3D Hologram Projector, you can view the test view at YouTube.

Read More..

Friday, April 29, 2016

Threading in Android part 1 Handlers

Multi-Threading concept is essential in most platforms. it provides maximum

utilization of the processor. threading is used when the program executes

time consuming processes (such as calling a web service) and to give a

good user experience by unblocking the UI.

Android provides threading techniques to perform time consuming tasks in a

background thread with coordination with the UI thread to update the UI.

Android provides the following methods of threading:
  1. Handlers.
  2. Async. Tasks.
Handlers:
When you create an object from the Handler class, it processes

Messages and Runnable objects associated with the

current thread MessageQueue. the message queue holds the

tasks to be executed in FIFO (First In First Out) mannser. you will need

only ine Handler per activity where the background thread will

communicate with to update the UI.

The Handler is associated with the thread from which its been created

We can communicate with the Handler by two methods:
  1. Messages.
  2. Runnable objects.
In this post we will demonstrate how to use both using a simple example which is

updating the text of a TextView using multiple threads.

Using Messages:

the steps of using a Handler are as follows:
  1. You create a Handler object with an asscociated callback

    method to handle the received messages (it is the method where the UI update

    will be done).
  2. From the background thread you will need to send messages to the

    handler.
Heres the code of our activity:
public class MainActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//display each item in a single line
txt.setText(txt.getText()+"Item "+System.getProperty("line.separator"));
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}

@Override
protected void onStart() {
super.onStart();
// create a new thread
Thread background=new Thread(new Runnable() {

@Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000); b.putString("My Key", "My Value:

"+String.valueOf(i));
// send message to the handler with the current message handler

handler.sendMessage(handler.obtainMessage());
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});

background.start();
}
}
after running the following code the TextView will display the following,

each second a new line is written:

This example is pretty basic, it just sends the same message for a number of

times.
what if we want the message sent to hold data thats changed each time the

message is sent, the answer is to use Message.setData(Bundle bundle)

method by creating a Bundle object and adding the data to it like this:
public class MainActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// get the bundle and extract data by key
Bundle b = msg.getData();
String key = b.getString("My Key");
txt.setText(txt.getText() + "Item " + key
+System.getProperty("line.separator"));
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
}

@Override
protected void onStart() {
super.onStart();
// create a new thread
Thread background = new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
Message msg = new Message();
Bundle b = new Bundle();
b.putString("My Key", "My Value: " + String.valueOf(i));
msg.setData(b);
// send message to the handler with the current message handler
handler.sendMessage(msg);
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});

background.start();
}
}
we put a string to the bundle and send a message with that bundle. in the

handler method we receive the bundle and get the value with the predefined key.
after executing that code the text view would look like this:

Using Runnables:
another way to use Handlers is to pass them a Runnable by using the

Handler.post() method like this:
Runnable r=new Runnable() {

@Override
public void run() {
txt.setText("Runnable");

}
};

handler.post(r);

this will add the Runanble object to the message queue to be executed by

the handler.

Sending Messages in a

timely manner:
we can use handlers to send messages or post runnables at time intervals using

the following methods:

  1. handler.sendEmptyMessageAtTime(int what,long uptimeMillis):sends an
     empty message at a specific time in milli-seconds, can be defined by using the
    SystemClock.uptimeMillis() method to get the time since the device boot
     in milli-seconds and concatinating to it.
  2. handler.sendEmptyMessageDelayed(int what,long delayMillis):sends an
     empty message after a certain amount of time in milli-seconds.
  3. handler.sendMessageAtTime(Message msg,long uptimeMillis).
  4. handler.sendMessageDelayed(Message msg,long delayMillis).
  5. handler.postAtTime(Runnable r,long uptimeMillis).
  6. handler.postAtTime(Runnable r,Object token,long uptimeMillis):posts a
     runnable with an object as a distinguishing token.
  7. handler.postDelayed(Runnable r,long delayMillis).
All the above messages return a boolean indicating whether the message or the

runnable has been placed successfully in the message queue.

Removing Call backs:
if you want to remove a runnable or a message from the message queue, you can

use the following methods:

  1. handler.removeCallbacks(Runnable r).
  2. handler.removeCallbacks(Runnable r,Object token).
  3. handler.removeCallbacksAndMessages(Object token).
  4. handler.removeMessages(int what).
  5. handler.removeMessages(int what,Object object)
Read More..

Tuesday, February 9, 2016

Android Menus Part 1 Options menu and sub menus

Android phones have the menu button which displays a menu with several items that provide navigation or more functionality or settings to your applications

Android has three types of menus
1. Options Menu
2. Context Menu
3. Sub menus

Menu items can be grouped and each menu item can have submenu items.

Options Menu

Each activity has a single menu. It appears when you press the menu button Each activity creates this menu in the callback method onCreateOptionsMenu you can override this method and add items to the menu.
If you press the menu button you will see the menu like this:
public class MenusDemo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("Item1");
menu.add("Item2");
return true;
}
}



Notice that the onCreateOptionsMenu method returns a Boolean. It should return true for the menu to appear, if returns false the menu will be invisible.

If you add many menu items, more than five items they will appear like this:
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1, 1, 0, "Item1");
menu.add(1, 2, 1, "Item2");
menu.add(1, 3, 2, "Item3");
menu.add(1, 4, 3, "Item4");
menu.add(1, 5, 4, "Item5");

menu.add(2, 6, 0, "Item6");
menu.add(2, 7, 1, "Item7");
menu.add(2, 8, 2, "Item8");
menu.add(2, 9, 3, "Item9");
menu.add(2, 10, 4, "Item10");



return true;
}



When you press on the “more” link you will see the rest of the menu items



The menu.add(int GroupID,int ItemID,int Order,String Title) method has the following parameters:
  1. GroupID: used to group related menu items to apply some configurations on all items of a certain group once at a time (discussed later) .
  2. ItemID: an integer to identify the menu item.
  3. Order: the sort order or the order ID, controls the order of menu items in a menu. Items with lower order id appear first. There are some constants defined for sort order for different kinds of menu items
    Like Menu.CATEGORY_SECONDRY for secondry menu items, Menu.CATEGORY_SYSTEM for system menu items and Menu.CATEGORY_ALTERNATIVE for altenative menu items..
  4. Title: the text of the menu item


We could have written the previous code using the predefined the sort order constants like this:
menu.add(1, 1, Menu.FIRST, "Item1");
menu.add(1, 2, Menu.FIRST+1, "Item2");
menu.add(1, 3, Menu.FIRST+2, "Item3");
menu.add(1, 4, Menu.FIRST+3, "Item4");
menu.add(1, 5, Menu.FIRST+4, "Item5");

menu.add(2, 6, Menu.CATEGORY_SECONDARY, "Item1");
menu.add(2, 7, Menu.CATEGORY_SECONDARY+1, "Item2");
menu.add(2, 8, Menu.CATEGORY_SECONDARY+2, "Item3");
menu.add(2, 9, Menu.CATEGORY_SECONDARY+3, "Item4");
menu.add(2, 10, Menu.CATEGORY_SECONDARY+4, "Item5");




Adding Icons to menu items:
We saw that only the first five items can appear in the options menu and the other items appear in a dialog when you press “more” item.
For the first five items you can add an icon to appear next to the items title:
menu.add(1, 1, 0, "Blu-Ray").setIcon(R.drawable.bluray);
menu.add(1, 2, 1, "DVD").setIcon(R.drawable.dvd);
menu.add(1, 3, 2, "Hard Disk").setIcon(R.drawable.hd);
menu.add(1, 4, 3, "Sites").setIcon(R.drawable.sites);
menu.add(1, 5, 4, "USB").setIcon(R.drawable.usb);

menu.add(2, 6, 5, "Item1");
menu.add(2, 7, 6, "Item2");
menu.add(2, 8, 7, "Item3");
menu.add(2, 9, 8, "Item4");
menu.add(2, 10, 9, "Item5");



Grouping Menu Items:

We saw that the method we use to add menu items us Menu.Add(GroupID,ItemId,OrderID,Title)
The first parameter is GroupID, what is it ? the answer leads us to grouping Menu Items.

Grouping menu items makes it easy to apply some options on some related menu items by applying these options on all menu items that belong to a group once instead of applying them on each single item at a time.

The actions that can be applied on a group can be:
  • Menu.removeGroup(int GroupID): to remove all menu items belonging to the same group.
  • Menu.setGroupCheckable(int GroupID,Boolean Checakble,Boolean Exclusive): maked a group appear with a check mark beside each item. If the Boolean Exclusive is set to true then the items will appear as if they are in a radiobuttongroup and only one item can be selected at a time. If set to false then they will appear with check boxes beside each item and multiple items can be selected at a time.
  • Menu.setGroupEnabled(int GroupID,Boolean Enabled): sets all items in a group to be enabled/disabled.
  • Menu.setGroupVisible(int GroupID,Boolean Visible): sets all items in a group to be visible/invisible.
Note: the methods mentioned above can be applied only to menu items in the secondary menu (items that appear when you click the more button)


Adding Alpha-Numeric shortcuts to menu Items:
You can add alphabetic or numeric shortcuts to menu items like this:
menu.add(2, 8, 7, "Item3").setNumericShortcut(3);
menu.add(2, 9, 8, "Item4").setAlphabeticShortcut(c);
then setting the querty mode of the menu to true like this:
menu.setQwertyMode(true);

and thats it for Androids options menu.

In a next post well talk about handling options menu events
Read More..