Android UI(2)Getting Started - Supporting Devices and Fragments
3. Supporting Different Devices
Supporting Different Languages
Keep the UI String to external file instead of in the Java Codes.
Create Locale Directories and String Files
Multiple languages
res/
values/
strings.xml
values-es/
strings.xml
values-ft/
strings.xml
Use the String Resources
In Java Codes
The syntax to refer to a string resource is R.string.<string_name>
In XML files
@string/<string_name>
Supporting Different Screens
4 sizes: small, normal, large, large
4 densities: low(LDPI), medium(MDPI), high(HDPI), extra high(XHDPI)
Create Different Layouts
res/
layout/
main.xml
layout-large/
main.xml
The system will reference the layout file as usual
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Create Different Bitmaps
@drawable/awesomeimage will reference to the bitmap.
Supporting Different Platform Versions
…snip…
4. Building a Dynamic UI with Fragments
Download the sample project FragmentBasics.zip
Using the Support Library
Set Up Your Project with the Support Library
Make sure I download the Extras/Android Support
Make sure I copy the jar from /opt/android-sdk/extras/android/support/v4/android-support-v4.jar to libs under my own project.
And change my configuration on Manifest file to
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17"/>
Import the Support Library APIs
…snip…
Creating a Fragment
A fragment is a muddler section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running. (sub activity which you can reuse in different activities)
Create a Fragment Class
Just extends the Fragment class.
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ArticleFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.article_view,container, false);
}
}
The lifecycle of Fragment is as like as Activity.
Add a Fragment to an Activity using XML
FragmentActivity is a special activity provided in the Support Library to handle fragments on system versions older than API level 11. After version 11, we can use a regular Activity.
<LinearLayout …>
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
Building a Flexible UI
The FragmentManager class provides methods that allow you to add, remove, and replace fragments to an activity at runtime.
Add a Fragment to an Activity at Runtime
We only define an empty container here
<FrameLayout …snip…
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Inside my activity, call getSupportFragmentManager() to get a FragmentManager using the Support Library APIs. Then call beginTransaction() to create a FragmentTransaction and call add() to add a fragment.
Commit the changes with commit().
HeadlinesFragment firstFragment = new HeadlinesFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();
Replace One Fragment with Another
Use the method replace() instead of add().
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position); //just remember which article we choose
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null); //make the back button working
transaction.commit();
Communicating with Other Fragments
All Fragment-to-Fragment communication is done through the associated Activity. 2 Fragments should never communicate directly.
Define an Interface
We define an interface and callback method, implement in Activity.
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
mCallback = (OnHeadlineSelectedListener)activity;
}catch(ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener");
}
}
}
Send the event to Activity
public void onListItemClick(ListView l, View v, int position, long id) {
mCallback.onArticleSelected(position);
}
The fragment bind the interface to Activity, send the event.
The activity will implement the interface.
Deliver a Message to a Fragment
If the fragment is there, directly call the method.
ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.articles_fragment);
if(articleFrag != null){
articleFrag.updateArticleView(position);
}else{
…snip...
}
References:
http://developer.android.com/training/basics/supporting-devices/index.html
http://developer.android.com/training/basics/fragments/creating.html
http://developer.android.com/training/basics/fragments/fragment-ui.html