Step By Step系列之Fragments(二)
转载请注明:转自http://blog.csdn.net/dhongmo/article/details/8575317
1.Fragments的应用
在
《Step By Step系列之Fragments(一)》里面简述了Fragments的基本应用,下面会通过官方的例子了解一下Fragments是如何在不同设备上的灵活性。主要关注的知识点有:动态添加Fragments、不同Fragments之间的数据传递、Fragments和back stack的结合使用等
2.Step By Step
Step1 添加support library
通过SDK Manger下载support library
在项目里创建libs文件夹,把android-support-v4.jar放进libs,然后导入到项目里
Step2 创建XML文件
// 文章的布局文件res/layout/article_view.xml//匹配小屏幕时的布局文件,只有一个Fragment<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/article" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:textSize="18sp" />
res/layout/news_articles.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
//匹配大屏幕时的布局文件,有两个Fragmentres/layout-large/article_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <fragment android:id="@+id/headlines_fragment" android:name="com.example.android.fragments.HeadlinesFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/article_fragment" android:name="com.example.android.fragments.ArticleFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" /> </LinearLayout>
Step3 创建Activity和Fragment
package com.example.android.fragments; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.util.Log; public class MainActivity extends FragmentActivity implements HeadlinesFragment.OnHeadlineSelectedListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); // 如果是小屏幕,我们就需要手动加载HeadlinesFragment。大屏幕的时候,已经在layout文件里绑定Fragment了,无需其他操作。 if (findViewById(R.id.fragment_container) != null) { Log.v("info", "R.id.fragment_container"); // 如果是恢复成旧状态就什么都不用做 if (savedInstanceState != null) { return; } // 1.创建Fragment HeadlinesFragment firstFragment = new HeadlinesFragment(); // 设置参数 firstFragment.setArguments(getIntent().getExtras()); // 2.获得FragmentManager,再获得beginTransaction,然后add,完成Fragment绑定到Activity getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit(); } } // 文章标题被点击时回调此函数,用于创建文章内容Fragment public void onArticleSelected(int position) { // 找到ArticleFragment ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById( R.id.article_fragment); // 若ArticleFragment已经存在,无需重新创建,直接更新文章内容即可 if (articleFrag != null) { articleFrag.updateArticleView(position); } else { // 若ArticleFragment不存在,则创建之 ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // 通过replace方法,把文章标题Fragment更换为文章内容Fragment transaction.replace(R.id.fragment_container, newFragment); // 添加到back stack,按返回键回滚到文章标题Fragment transaction.addToBackStack(null); // 记得提交事务,才有效果 transaction.commit(); } } }
package com.example.android.fragments; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // 定义一个接口,当标题栏被点击时触发 public interface OnHeadlineSelectedListener { /** Called by HeadlinesFragment when a list item is selected */ public void onArticleSelected(int position); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1; // 设置Adapter setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines)); } @Override public void onStart() { super.onStart(); // 如果是大屏幕,文章标题设为高亮 if (getFragmentManager().findFragmentById(R.id.article_fragment) != null) { getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); // 确保继承OnHeadlineSelectedListener接口,否则抛出异常 try { mCallback = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } } @Override public void onListItemClick(ListView l, View v, int position, long id) { // 调用回调函数,传递被点击的位置 mCallback.onArticleSelected(position); // 被点击位置设为高亮 getListView().setItemChecked(position, true); } }
package com.example.android.fragments; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class ArticleFragment extends Fragment { final static String ARG_POSITION = "position"; int mCurrentPosition = -1; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 通过savedInstanceState来记录当前的文章内容 if (savedInstanceState != null) { mCurrentPosition = savedInstanceState.getInt(ARG_POSITION); } return inflater.inflate(R.layout.article_view, container, false); } @Override public void onStart() { super.onStart(); // 更新文章内容 Bundle args = getArguments(); if (args != null) { updateArticleView(args.getInt(ARG_POSITION)); } else if (mCurrentPosition != -1) { updateArticleView(mCurrentPosition); } } public void updateArticleView(int position) { TextView article = (TextView) getActivity().findViewById(R.id.article); article.setText(Ipsum.Articles[position]); mCurrentPosition = position; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存当前文章的状态 outState.putInt(ARG_POSITION, mCurrentPosition); } }
3.源代码
点击下载