Saturday, June 30, 2012
Google I/O 2012 - Google Play: Marketing 101 for Developers
As soon as you hit the "Publish" button on your app, you become (partly) a marketer; you might as well try to be a good one. We'll share everything we know about promoting apps on Google play: building a strategic marketing framework, making good use of media channels, taking advantage of the assets we've built for developers, and convincing the Play team to feature your app.
Friday, June 29, 2012
Thursday, June 28, 2012
Various Navigation Type provided in new Android SDK Tools, Revision 20.
In addition to the Master Detail Flow template described in last post, Android SDK Tools Revision 20 also provide various Navigation Type for Blank activity.
To use the template of Navigation Type, minimum SDK version of at least 14 is required.
Provided templates include:
- Tabs
- Tabs + Swipe
- Swipe Views + Title Strip
- Dropdown
It's a example of Swipe Views + Title Strip:
And the auto-generated code:
To use the template of Navigation Type, minimum SDK version of at least 14 is required.
Provided templates include:
- Tabs
- Tabs + Swipe
- Swipe Views + Title Strip
- Dropdown
It's a example of Swipe Views + Title Strip:
And the auto-generated code:
package com.example.androidr20a;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
* sections. We use a {@link android.support.v4.app.FragmentPagerAdapter} derivative, which will
* keep every loaded fragment in memory. If this becomes too memory intensive, it may be best
* to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
* sections of the app.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return getString(R.string.title_section1).toUpperCase();
case 1: return getString(R.string.title_section2).toUpperCase();
case 2: return getString(R.string.title_section3).toUpperCase();
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
public DummySectionFragment() {
}
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
Bundle args = getArguments();
textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
return textView;
}
}
}
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--
This title strip will display the currently visible page title, as well as the page
titles for adjacent pages.
-->
<android.support.v4.view.PagerTitleStrip android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
Android SDK Tools, Revision 20 now support Application templates
Lets walk through the new project wizard of Android SDK Tools Revision 20 to create a Master Detail Flow Hello World.
- As normal, click File - > New to create a new project
- Select Android Application Project under Android, and click Next>.
- Setup a new project, include select Build SDK and Minimum Required SDK, click Next>.
- Configure Launcher Icon.
- New Android ADT now supports new application templates for creating new application:
- Accept the default setting of the New Master/Detail Flow at this moment, click Finish.
Lets run the new Hello World generated.
- Now you can select how monitor logcat.
- Run on Android Phone Galaxy Nexus, still running 4.0.2!
- Run on Android Tablet HTC Flyer, running 3.2.1.
Related:
- Various Navigation Type provided in new Android SDK Tools, Revision 20.
- Life cycle of MasterDetailFlow HelloWorld
- As normal, click File - > New to create a new project
- Select Android Application Project under Android, and click Next>.
- Setup a new project, include select Build SDK and Minimum Required SDK, click Next>.
- Configure Launcher Icon.
- New Android ADT now supports new application templates for creating new application:
- Blank activity: Creates a new blank activity, with optional inner navigation.
- Master Detail Flow: Creates a new master/detail flow, which is two columns on tablets, and one column on smaller screens. This creates a master fragment, detail fragment, and two activities.
- Accept the default setting of the New Master/Detail Flow at this moment, click Finish.
Lets run the new Hello World generated.
- Now you can select how monitor logcat.
- Run on Android Phone Galaxy Nexus, still running 4.0.2!
- Run on Android Tablet HTC Flyer, running 3.2.1.
Related:
- Various Navigation Type provided in new Android SDK Tools, Revision 20.
- Life cycle of MasterDetailFlow HelloWorld
Wednesday, June 27, 2012
Jelly Bean will be rolling out to Galaxy Nexus, Nexus S and Xoom devices in mid July
According to engadget, Jelly Bean will be rolling out to Galaxy Nexus, Nexus S and Xoom devices in mid July, along with the open source code. Developers though, can start playing with the SDK today.
Source: http://www.engadget.com/2012/06/27/jelly-bean-android-4-1-revealed-by-google/
Source: http://www.engadget.com/2012/06/27/jelly-bean-android-4-1-revealed-by-google/
Android 4.1 (Jelly Bean) preview platform announced
At Google I/O, the latest version of the Android platform, Android 4.1 (Jelly Bean), was announced. With Jelly Bean, we’ve made the great things about Android even better with improved system performance and enhanced user features.
Android 4.1 is the fastest and smoothest version of Android yet. Google have made improvements throughout the platform and added great new features for users and developers. This document, Android 4.1 for Developers, provides a glimpse of what's new for developers.
See the Android 4.1 APIs document for a detailed look at the new developer APIs.
Source: Android Developers Blog - Introducing Android 4.1 (Jelly Bean) preview platform, and more
Life cycle of Fragment
In order to work with Fragment, Lifecycle of Fragment is a must known issue.
It's a experience to know Lifecycle of Fragment. It display the called lifecycle relate method on screen. Via this experience, you (and me) can know more about it.
Create /res/layout/fragmentlayout.xml, the layout of the fragment.
MyFragment.java, extends Fragment.
The main activity, AndroidExFragmentActivity.java.
main.xml, the main layout to include our fragment.
Download the files.
Related:
- Life cycle of MasterDetailFlow HelloWorld
It's a experience to know Lifecycle of Fragment. It display the called lifecycle relate method on screen. Via this experience, you (and me) can know more about it.
Create /res/layout/fragmentlayout.xml, the layout of the fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
MyFragment.java, extends Fragment.
package com.exercise.AndroidExFragment;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragmentlayout, container, false);
updateMyStatus("onCreateView()");
return myFragmentView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
updateMyStatus("onActivityCreated()");
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
updateMyStatus("onAttach()");
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
updateMyStatus("onCreate()");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
updateMyStatus("onDestroy()");
}
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
updateMyStatus("onDestroyView()");
}
@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
updateMyStatus("onDetach()");
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
updateMyStatus("onPause()");
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
updateMyStatus("onResume()");
}
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
updateMyStatus("onStart()");
}
@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
updateMyStatus("onStop()");
}
private void updateMyStatus(String myst){
((AndroidExFragmentActivity)getActivity()).updateStatus(" >> MyFragment: " + myst);
}
}
The main activity, AndroidExFragmentActivity.java.
package com.exercise.AndroidExFragment;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class AndroidExFragmentActivity extends Activity {
TextView status;
String myStatus = "";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
status = (TextView)findViewById(R.id.status);
updateMyStatus("onCreate()");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
updateMyStatus("onDestroy()");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
updateMyStatus("onPause()");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
updateMyStatus("onResume()");
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
updateMyStatus("onStart()");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
updateMyStatus("onStop()");
}
private void updateMyStatus(String myst){
updateStatus("Activity: " + myst);
}
public void updateStatus(String st){
if(status == null){
myStatus += "delay - " + st + "\n";
}else{
myStatus += st + "\n";
status.setText(myStatus);
}
}
}
main.xml, the main layout to include our fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<ScrollView
android:layout_width="0px"
android:layout_weight="3"
android:layout_height="match_parent">
<TextView
android:id="@+id/status"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#555555"/>
</ScrollView>
<fragment
class="com.exercise.AndroidExFragment.MyFragment"
android:id="@+id/myfragment"
android:layout_width="0px"
android:layout_weight="2"
android:layout_height="match_parent" />
</LinearLayout>
Download the files.
Related:
- Life cycle of MasterDetailFlow HelloWorld
Tuesday, June 26, 2012
java.lang.NoClassDefFoundError: com.google.ads.AdView
If you have Android Apps with admob, and you update admob API with current ADT (may be ADT-17 or later), may be your code can be compiled without error, but fail in run-time, caused by java.lang.NoClassDefFoundError: com.google.ads.AdView!
It seem to be problem in ADT with external jars. To solve it:
- Create a libs folder in your project.
- Copy AdMob jar, GoogleAdMobAdsSdk-6.0.1.jar, in the libs folder.
- Update Java Build Path by selecting "Add JARs..." (NOT "Add External JARs...") to add the jar in libs.
It seem to be problem in ADT with external jars. To solve it:
- Create a libs folder in your project.
- Copy AdMob jar, GoogleAdMobAdsSdk-6.0.1.jar, in the libs folder.
- Update Java Build Path by selecting "Add JARs..." (NOT "Add External JARs...") to add the jar in libs.
Qualcomm announce Snapdragon SDK for Android, now available for Public Preview.
The Snapdragon SDK for Android has what you’d expect in any SDK: new APIs implemented using Android extensions, grouped in software packages by function, along with the docs and sample code you need to start writing to them.
The Snapdragon SDK for Android is a collection of software components that can be downloaded to enhance your app – especially when it's running on Snapdragon Processor powered devices. It is designed to make it easy for developers and device makers to take advantage of a host of next-gen technologies – from low power, always-on geo-fencing, to complex facial recognition and superfast computer vision, to dual mic stereo audio recording.
Visit Snapdragon SDK for Android Public Preview in QDeveNet
Monday, June 25, 2012
Android ICS Emulator for Mac OS with Intel® Hardware Accelerated Execution Manager
Eric Adams, a Software Engineer at Intel, will show you step-by-step how to download and install on Mac the latest Android ICS emulator for x86.
Android ICS Emulator for Ubuntu with KVM acceleration supported by Intel VT-x
Eric Adams, a Software Engineer at Intel, will show you step-by-step how to download and install on Ubuntu the latest Android ICS emulator for x86.
Android ICS Emulator for Microsoft Windows with Intel® Hardware Accelerated Execution Manager
Eric Adams, a Software Engineer at Intel, will show you step-by-step how to download and install on Windows the latest Android ICS emulator for x86.
Developing Android Apps with the Intel® Hardware Accelerated Execution Manager
The Benefits of Developing Android Apps with the Intel® Hardware Accelerated Execution Manager
This video shows how any Android developer using an Intel® Architecture (IA) based host PC with Windows, Mac or Linux can greatly speed up Android emulation by leveraging Intel® Virtualization Technology. Side by side comparisons show the performance gains of using the free Intel® HAXM driver with the Intel® x86 Atom™ System Image to deliver much faster boot times, game play, and app execution. Whether you’re coding in Dalvik Java or C/C++ (for NDK apps), and regardless of whether you’re targeting ARM or IA-based smartphones or tablets, this solution will deliver a far superior Android emulation experience for faster testing and debug of your Android apps.
This video shows how any Android developer using an Intel® Architecture (IA) based host PC with Windows, Mac or Linux can greatly speed up Android emulation by leveraging Intel® Virtualization Technology. Side by side comparisons show the performance gains of using the free Intel® HAXM driver with the Intel® x86 Atom™ System Image to deliver much faster boot times, game play, and app execution. Whether you’re coding in Dalvik Java or C/C++ (for NDK apps), and regardless of whether you’re targeting ARM or IA-based smartphones or tablets, this solution will deliver a far superior Android emulation experience for faster testing and debug of your Android apps.
Sunday, June 24, 2012
AsyncTask run in background thread of a invisible Fragment of ViewPager
Further exercise from last post "Communication between Fragments in ViewPager".
When a button in MyFragmentA clicked, it will start a AsyncTask in MyFragmentC, running in background and update a ProgressBar. When the ProgressBar finished, it will update MyFragmentB. It can be noted that the AsyncTask run in background even MyFragmentC is not in visible screen.
Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a Butten to start AsyncTask in MyFragmentC.
Modify MyFragmentC.java and /res/layout/fragment_c.xml to add a ProgressBar and implement AsyncTask.
main activity, AndroidViewPagerActivity.java
Download the files.
When a button in MyFragmentA clicked, it will start a AsyncTask in MyFragmentC, running in background and update a ProgressBar. When the ProgressBar finished, it will update MyFragmentB. It can be noted that the AsyncTask run in background even MyFragmentC is not in visible screen.
Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a Butten to start AsyncTask in MyFragmentC.
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyFragmentA extends Fragment {
EditText A_input;
Button A_enter;
Button A_startCProgress;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
A_input = (EditText)myFragmentView.findViewById(R.id.a_input);
A_enter = (Button)myFragmentView.findViewById(R.id.a_enter);
A_enter.setOnClickListener(A_enterOnClickListener);
A_startCProgress = (Button)myFragmentView.findViewById(R.id.a_startcprogress);
A_startCProgress.setOnClickListener(A_startCProgressOnClickListener);
return myFragmentView;
}
OnClickListener A_startCProgressOnClickListener
= new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String TabOfFragmentC = ((AndroidViewPagerActivity)getActivity()).getTabFragmentC();
MyFragmentC fragmentC = (MyFragmentC)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentC);
fragmentC.StartProgress();
}
};
OnClickListener A_enterOnClickListener
= new OnClickListener(){
@Override
public void onClick(View arg0) {
String textPassToB = A_input.getText().toString();
String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText(textPassToB);
Toast.makeText(getActivity(),
"text sent to Fragment B:\n " + TabOfFragmentB,
Toast.LENGTH_LONG).show();
}};
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<EditText
android:id="@+id/a_input"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/a_enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter to Fragment B"/>
<Button
android:id="@+id/a_startcprogress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Async Progress in Fragment C"/>
</LinearLayout>
Modify MyFragmentC.java and /res/layout/fragment_c.xml to add a ProgressBar and implement AsyncTask.
package com.exercise.AndroidViewPager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
public class MyFragmentC extends Fragment {
ProgressBar cProgress;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);
String myTag = getTag();
((AndroidViewPagerActivity)getActivity()).setTabFragmentC(myTag);
cProgress = (ProgressBar)myFragmentView.findViewById(R.id.progressbar);
return myFragmentView;
}
public void StartProgress(){
new ProgressAsyncTask().execute();
}
public class ProgressAsyncTask extends
AsyncTask<Void, Integer, Void> {
int myProgress;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
myProgress = 0;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText("Progress finished!");
}
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
while(myProgress<100){
myProgress++;
publishProgress(myProgress);
SystemClock.sleep(100);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
cProgress.setProgress(values[0]);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment C" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:progress="0"
android:max="100"/>
</LinearLayout>
main activity, AndroidViewPagerActivity.java
package com.exercise.AndroidViewPager;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class AndroidViewPagerActivity extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TabFragmentB;
String TabFragmentC;
public void setTabFragmentB(String t){
TabFragmentB = t;
}
public String getTabFragmentB(){
return TabFragmentB;
}
public void setTabFragmentC(String t){
TabFragmentC = t;
}
public String getTabFragmentC(){
return TabFragmentC;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
MyFragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
MyFragmentB.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
MyFragmentC.class, null);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getCount() {
return mTabs.size();
}
}
}
Download the files.
Saturday, June 23, 2012
Communication between Fragments in ViewPager
In Previous exercise "ViewPager" (and fix of "NullPointerException of ViewPager when change orientation"), I create a ViewPager with three independent Fragments. Now, I want to make some input (EditText) from Fragment A, then transfer it to Fragment B.
With FragmentManager, we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>). But, what's the tag of Fragment B? I can't found any method something like setTag()!
Luckly; I found getTag() method to get the tag name of current fragment. So I create a mechanism to access the tag across fragments via the main activity, AndroidViewPagerActivity. - Call getTag() in onCreateView() of MyFragmentB. Then pass it to the main activity AndroidViewPagerActivity. When MyFragmentA need to pass something to MyFragmentB, it retrieve it from AndroidViewPagerActivity.
Modify the main activity, AndroidViewPagerActivity.java, to have a String TabFragmentB; and implement setTabFragmentB() and getTabFragmentB() to access it.
Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a ExitText and a Butten to send something.
Modify MyFragmentB.java and /res/layout/fragment_b.xml to receive something.
Download the files.
Next:
- AsyncTask run in background thread of a invisible Fragment of ViewPager
Please notice:
This exercise aim to demonstrate how to communicate between Fragments in ViewPager. But, you have to take care about live-cycle of the Fragments. For example, may be the target Fragment have not yet created when data is passed. Or, the Fragment have been destroyed after data passed. Read more: Life cycle of Fragments in ViewPager.
With FragmentManager, we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>). But, what's the tag of Fragment B? I can't found any method something like setTag()!
Luckly; I found getTag() method to get the tag name of current fragment. So I create a mechanism to access the tag across fragments via the main activity, AndroidViewPagerActivity. - Call getTag() in onCreateView() of MyFragmentB. Then pass it to the main activity AndroidViewPagerActivity. When MyFragmentA need to pass something to MyFragmentB, it retrieve it from AndroidViewPagerActivity.
Modify the main activity, AndroidViewPagerActivity.java, to have a String TabFragmentB; and implement setTabFragmentB() and getTabFragmentB() to access it.
package com.exercise.AndroidViewPager;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class AndroidViewPagerActivity extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TabFragmentB;
public void setTabFragmentB(String t){
TabFragmentB = t;
}
public String getTabFragmentB(){
return TabFragmentB;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
MyFragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
MyFragmentB.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
MyFragmentC.class, null);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getCount() {
return mTabs.size();
}
}
}
Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a ExitText and a Butten to send something.
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyFragmentA extends Fragment {
EditText A_input;
Button A_enter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
A_input = (EditText)myFragmentView.findViewById(R.id.a_input);
A_enter = (Button)myFragmentView.findViewById(R.id.a_enter);
A_enter.setOnClickListener(A_enterOnClickListener);
return myFragmentView;
}
OnClickListener A_enterOnClickListener
= new OnClickListener(){
@Override
public void onClick(View arg0) {
String textPassToB = A_input.getText().toString();
String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText(textPassToB);
Toast.makeText(getActivity(),
"text sent to Fragment B:\n " + TabOfFragmentB,
Toast.LENGTH_LONG).show();
}};
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<EditText
android:id="@+id/a_input"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/a_enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter to Fragment B"/>
</LinearLayout>
Modify MyFragmentB.java and /res/layout/fragment_b.xml to receive something.
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
public class MyFragmentB extends Fragment {
TextView b_received;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
b_received = (TextView)myFragmentView.findViewById(R.id.b_received);
String myTag = getTag();
((AndroidViewPagerActivity)getActivity()).setTabFragmentB(myTag);
Toast.makeText(getActivity(),
"MyFragmentB.onCreateView(): " + myTag,
Toast.LENGTH_LONG).show();
return myFragmentView;
}
public void b_updateText(String t){
b_received.setText(t);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment B" />
<TextView
android:id="@+id/b_received"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
Download the files.
Next:
- AsyncTask run in background thread of a invisible Fragment of ViewPager
Please notice:
This exercise aim to demonstrate how to communicate between Fragments in ViewPager. But, you have to take care about live-cycle of the Fragments. For example, may be the target Fragment have not yet created when data is passed. Or, the Fragment have been destroyed after data passed. Read more: Life cycle of Fragments in ViewPager.
Friday, June 22, 2012
NullPointerException of ViewPager when change orientation
In my last exercise of "ViewPager", when change orientation, NullPointerException will be thrown in onSaveInstanceState()!
May be it's a bug in ViewPager. Note the class ViewPager is currently under early design and development. May be it will be fixed in later updates.
At this moment, my solution is to comment the statement to call super.onSaveInstanceState(outState).
Next:
- Communication between Fragments in ViewPager
May be it's a bug in ViewPager. Note the class ViewPager is currently under early design and development. May be it will be fixed in later updates.
At this moment, my solution is to comment the statement to call super.onSaveInstanceState(outState).
@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
Next:
- Communication between Fragments in ViewPager
ViewPager
android.support.v4.view.ViewPager is Layout manager that allows the user to flip left and right through pages of data.
Note this class is currently under early design and development. The API will likely change in later updates of the compatibility library, requiring changes to the source code of apps when they are compiled against the newer version.
(This example implement ViewPager using FragmentPagerAdapter. For ViewPager using custom PagerAdapter, read HERE.)
To use compatibility library, Android Support Package is needed. Refer to last post to "Add Android Support Package".
Create three Fragments, each one corresponding to one tab. Please note that the Fragment(s) extends android.support.v4.app.Fragment.
MyFragmentA.java
/res/layout/fragment_a.xml
MyFragmentB.java
/res/layout/fragment_b.xml
MyFragmentC.java
/res/layout/fragment_c.xml
Main code, AndroidViewPagerActivity.java
Download the files.
!!! It's a bug here: when change orientation, NullPointerException will be thrown. Please refer to next post "NullPointerException of ViewPager when change orientation" for my solution.
Next:
- Communication between Fragments in ViewPager
- ViewPager example, with switching page programmatically
Related:
- ActionBar in Tab navigation mode
Note this class is currently under early design and development. The API will likely change in later updates of the compatibility library, requiring changes to the source code of apps when they are compiled against the newer version.
(This example implement ViewPager using FragmentPagerAdapter. For ViewPager using custom PagerAdapter, read HERE.)
To use compatibility library, Android Support Package is needed. Refer to last post to "Add Android Support Package".
Create three Fragments, each one corresponding to one tab. Please note that the Fragment(s) extends android.support.v4.app.Fragment.
MyFragmentA.java
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
return myFragmentView;
}
}
/res/layout/fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
MyFragmentB.java
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentB extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
return myFragmentView;
}
}
/res/layout/fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment B" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
MyFragmentC.java
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentC extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);
return myFragmentView;
}
}
/res/layout/fragment_c.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment C" />
</LinearLayout>
Main code, AndroidViewPagerActivity.java
package com.exercise.AndroidViewPager;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class AndroidViewPagerActivity extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
MyFragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
MyFragmentB.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
MyFragmentC.class, null);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getCount() {
return mTabs.size();
}
}
}
Download the files.
!!! It's a bug here: when change orientation, NullPointerException will be thrown. Please refer to next post "NullPointerException of ViewPager when change orientation" for my solution.
Next:
- Communication between Fragments in ViewPager
- ViewPager example, with switching page programmatically
Related:
- ActionBar in Tab navigation mode
Add Android Support Package
I have a old post "Install and setup Compatibility Package" describe how to include Android Support Package in Java Build Path. I try again it recently, it seem that the method no longer work! When work with android.support.v4.app.FragmentActivity, java.lang.ClassNotFoundException will be thrown.
It can be solved by Add Support Library in Eclipse menu.
- New a Android project target Android 3.0 (API Level 11).
- Modify AndroidManifest.xml to specify minSdkVersion and targetSdkVersion:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11"/>
- Add Android Support Library.
Right click on the project in Eclipse, select Android Tools, Add Support Library...
Accept to install Android Support.
- Test it
Modify your activity extends FragmentActivity instead Activity, and import android.support.v4.app.FragmentActivity.
Now you can run it without error.
It can be solved by Add Support Library in Eclipse menu.
- New a Android project target Android 3.0 (API Level 11).
- Modify AndroidManifest.xml to specify minSdkVersion and targetSdkVersion:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11"/>
- Add Android Support Library.
Right click on the project in Eclipse, select Android Tools, Add Support Library...
Accept to install Android Support.
- Test it
Modify your activity extends FragmentActivity instead Activity, and import android.support.v4.app.FragmentActivity.
Now you can run it without error.
Thursday, June 21, 2012
How to NFC
Google I/O 2011: How to NFC
Gingerbread brings a comprehensive NFC reader/writer API, and some modest but surprisingly powerful P2P support. Come hear why you should care about NFC technology, what kinds of applications are possible right now, and best practices for deployment.
Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices.
Gingerbread brings a comprehensive NFC reader/writer API, and some modest but surprisingly powerful P2P support. Come hear why you should care about NFC technology, what kinds of applications are possible right now, and best practices for deployment.
Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices.
Wednesday, June 20, 2012
Create ActionBar in Tab navigation mode
New a Android project target Android 3.2, API Level 13.
Create three Fragments, each one corresponding to one tab.
MyFragmentA.java
package com.exercise.AndroidNavigationTabs;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
return myFragmentView;
}
}
/res/layout/fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
MyFragmentB.java
package com.exercise.AndroidNavigationTabs;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentB extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
return myFragmentView;
}
}
/res/layout/fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment B" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
MyFragmentC.java
package com.exercise.AndroidNavigationTabs;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragmentC extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);
return myFragmentView;
}
}
/res/layout/fragment_c.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment C" />
</LinearLayout>
Main code, AndroidNavigationTabsActivity.java
package com.exercise.AndroidNavigationTabs;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
public class AndroidNavigationTabsActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tabA = actionBar.newTab();
tabA.setText("Tab A");
tabA.setTabListener(new TabListener<MyFragmentA>(this, "Tag A", MyFragmentA.class));
actionBar.addTab(tabA);
Tab tabB = actionBar.newTab();
tabB.setText("Tab B");
tabB.setTabListener(new TabListener<MyFragmentB>(this, "Tag B", MyFragmentB.class));
actionBar.addTab(tabB);
Tab tabC = actionBar.newTab();
tabC.setText("Tab C");
tabC.setTabListener(new TabListener<MyFragmentC>(this, "Tag C", MyFragmentC.class));
actionBar.addTab(tabC);
if (savedInstanceState != null) {
int savedIndex = savedInstanceState.getInt("SAVED_INDEX");
getActionBar().setSelectedNavigationItem(savedIndex);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putInt("SAVED_INDEX", getActionBar().getSelectedNavigationIndex());
}
public static class TabListener<T extends Fragment>
implements ActionBar.TabListener{
private final Activity myActivity;
private final String myTag;
private final Class<T> myClass;
public TabListener(Activity activity, String tag, Class<T> cls) {
myActivity = activity;
myTag = tag;
myClass = cls;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Fragment myFragment = myActivity.getFragmentManager().findFragmentByTag(myTag);
// Check if the fragment is already initialized
if (myFragment == null) {
// If not, instantiate and add it to the activity
myFragment = Fragment.instantiate(myActivity, myClass.getName());
ft.add(android.R.id.content, myFragment, myTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(myFragment);
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Fragment myFragment = myActivity.getFragmentManager().findFragmentByTag(myTag);
if (myFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(myFragment);
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
}
Download the files.
Related:
- ViewPager
Sunday, June 17, 2012
Split Action Bar for Android 4
The old article demonstrate how to "Create ActionBar using XML" for Android 3.
When your application is running on Android 4.0 (API level 14) and higher, there's an extra mode available for the action bar called "split action bar." When you enable split action bar, a separate bar appears at the bottom of the screen to display all action items when the activity is running on a narrow screen (such as a portrait-oriented handset). Splitting the action bar to separate the action items ensures that a reasonable amount of space is available to display all your action items on a narrow screen, while leaving room for navigation and title elements at the top.
To enable split action bar, simply add uiOptions="splitActionBarWhenNarrow" to your <activity> or <application> manifest element.
Split Action Bar:
Normal Action Bar:
- Add android:uiOptions="splitActionBarWhenNarrow" in AndroidManifest.xml.
- /res/menu/menu.xml define the items in Action Bar.
- Override onCreateOptionsMenu() method to inflate menu.
When your application is running on Android 4.0 (API level 14) and higher, there's an extra mode available for the action bar called "split action bar." When you enable split action bar, a separate bar appears at the bottom of the screen to display all action items when the activity is running on a narrow screen (such as a portrait-oriented handset). Splitting the action bar to separate the action items ensures that a reasonable amount of space is available to display all your action items on a narrow screen, while leaving room for navigation and title elements at the top.
To enable split action bar, simply add uiOptions="splitActionBarWhenNarrow" to your <activity> or <application> manifest element.
Split Action Bar:
Normal Action Bar:
- Add android:uiOptions="splitActionBarWhenNarrow" in AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidSplitActionBar"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:uiOptions="splitActionBarWhenNarrow"
android:name=".AndroidSplitActionBarActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- /res/menu/menu.xml define the items in Action Bar.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/itemid_0"
android:title="Action Item 0"
android:icon="@drawable/ic_launcher"
android:orderInCategory="0"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/itemid_1"
android:title="Action Item 1"
android:orderInCategory="0"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/itemid_2"
android:title="Action Item 2"
android:orderInCategory="0"
android:showAsAction="ifRoom|withText" />
</menu>
- Override onCreateOptionsMenu() method to inflate menu.
package com.exercise.AndroidSplitActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public class AndroidSplitActionBarActivity 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) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
}
Saturday, June 16, 2012
Programmatically create layout and view, with ID assigned by setId().
This example demonstrate how to create layout and view at run time using Java code, instead of XML code. We can assign IDs for the layouts/views by calling setId() mdthod.
In order to call setId() with named id, create /res/values/ids.xml to define out ID resources.
Main code.
In order to call setId() with named id, create /res/values/ids.xml to define out ID resources.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="layout_id"/>
<item type="id" name="image_id" />
</resources>
Main code.
package com.exercise.AndroidSetId;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
public class AndroidSetIdActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(AndroidSetIdActivity.this);
layout.setId(R.id.layout_id);
LayoutParams layoutParams
= new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
layout.setLayoutParams(layoutParams);
layout.setOrientation(LinearLayout.VERTICAL);
ImageView imageView = new ImageView(AndroidSetIdActivity.this);
imageView.setId(R.id.image_id);
imageView.setImageResource(R.drawable.ic_launcher);
LayoutParams imageViewLayoutParams
= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
imageView.setLayoutParams(imageViewLayoutParams);
layout.addView(imageView);
setContentView(layout);
layout.setOnClickListener(viewOnClickListener);
imageView.setOnClickListener(viewOnClickListener);
}
OnClickListener viewOnClickListener
= new OnClickListener(){
@Override
public void onClick(View v) {
int myId = v.getId();
Toast.makeText(AndroidSetIdActivity.this,
"ID: " + String.valueOf(myId) + " clicked",
Toast.LENGTH_LONG).show();
}};
}
Schedule of Android Sessions in Google IO 2012
Be among the first to see the latest demos and developments from Android. Watch the keynote and over 40 sessions live streamed from Google I/O! It all begins June 27, at 9am.
Check the Android sessions schedule.
Check the Android sessions schedule.
Improve Android Emulator performance with Intel Atom x86 System Image
Back to the releasing of Android SDK r17, Intel Atom x86 System Image was included. AVD with Intel Atom x86 System Image can access the host CPU natively and offer significantly faster execution.
To install Intel Atom x86 System Image, click Window from Eclipse menu, select Android SDK Manager. Check to install package of Intel Atom x86 System Image, it's available on Android 4.0.3(API 15) and 2.3.3(API 10) currently.
Create emulator using Intel Atom x86 System Image
- Window -> AVD Manager. New a AVD.
- Select CPU/ABI of Intel Atom (x86). Enter others as needed. Click Create AVD.
To install Intel Atom x86 System Image, click Window from Eclipse menu, select Android SDK Manager. Check to install package of Intel Atom x86 System Image, it's available on Android 4.0.3(API 15) and 2.3.3(API 10) currently.
Create emulator using Intel Atom x86 System Image
- Window -> AVD Manager. New a AVD.
- Select CPU/ABI of Intel Atom (x86). Enter others as needed. Click Create AVD.
Subscribe to:
Posts (Atom)