您的位置:首页 > 移动开发 > Android开发

android Fragment 入门

2015-07-25 20:18 543 查看
  首先,先放出这次blog的演示demo,你需要使用android studio才能够打开它了,http://download.csdn.net/detail/tgbus18990140382/8933151

先来说说fragment是个什么东西。fragment是android3.0引入的设计理念,可以在用户不切换activity的情况下即时更新界面,fragment设计实际上和activity十分相似,fragment拥有activity的大部分重要的生命周期函数,你也可以近似的将fragment看作是activity

以下是fragment生命周期:



  图中我们可以看出fragment通过onAttach方法将生命周期和activity相关联,所以每个fragment可以看作是一个独立的activity。其中不同的是onCreateView方法中你需要返回fragment的view内容,onActivityCreated方法会通知fragment
activity创建成功,在activity结束onDestory之前会调用onDestoryView方法销毁fragment中的view以释放内存。

  其他详细内容可参考android官方api refrence,这里我们就不再赘述了,下面我们就来详细说说如何使用fragment。
  我们可以近似的将fragment看作为activity,其不同之处以上已经做了大概的描述,因此我们使用fragment是也可以像使用activity一样简单。fragment可以作为独立的组建在各个activity中使用,提高了ui组建的重用率。下面我们看下如何静态的定义一个fragment:
  首先,我们新建一个类TitleFragment并继承自ListFragment(它是Fragment的子类,这里为了方便使用我们使用ListFragment,其与ListActivity类似),一般的我们创建一个fragment需要复写onCreateView方法并且返回创建完的view,但是这里我们使用的是ListFragment系统已经帮我们创建了相应的view,因此这里我们不需要复写onCreateView方法。我们需要为list设置adapter,这里我们复写onActivityCreated方法为ListFragment设置adapter,完整的Fragment的代码如下(其中需要的一些资源未包含其中):

/**
 * Created by OnlynightZhang on 2015/7/9.
 *
 */
public class TitlesFragment extends ListFragment{

    public List<String> TITLES;

    private TitlesItemClickListener listener;

    /**
     * fragment添加到activity上的时候首先会调用onAttach方法,
     * 如果container activity实现了{@TitlesItemClickListener}监听器的话,
     * 我们就可以在该方法中将acitivity强转为{@TitlesItemClickListener},
     * 方便fragment与activity通信
     * @param activity
     */
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        /**
         * 初始化监听器通信接口
         */
        try{
            listener = (TitlesItemClickListener)activity;
        }catch( ClassCastException e ){
            e.printStackTrace();
        }

        /**
         * 初始化界面显示用的list data
         */
        TITLES = new ArrayList<>();
        for (Article article: Articles.ShakespeareArticles ){
            TITLES.add( article.getTitle() );
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        /**
         * 创建adapter,并将其设置到fragment上
         */
        ArrayAdapter<String> adapter = new ArrayAdapter<>( getActivity(), android.R.layout.simple_expandable_list_item_1, TITLES );
        setListAdapter(adapter);

        /**
         * 当切换到横屏后,自动选中第一个fragment
         */
        if ( getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ){
            listener.onItemClick( 0, TITLES.get( 0 ) );
        }
    }

    /**
     * 复写该方法,用于接收点击事件
     * @param l
     * @param v
     * @param position
     * @param id
     */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {

        /**
         * 如果fragment的container activity实现了{@TitlesItemClickListener}的话,
         * 那么activtiy就能够接收到相应的事件
         */
        if ( listener != null ){
            listener.onItemClick( position, TITLES.get( position ) );
        }
    }

    /**
     * fragment与container activity通信用的监听器接口
     */
    public interface TitlesItemClickListener{
        void onItemClick( int position, String title );
    }
}


接下来我们需要在activity中使用Fragment,我们在要是使用的activtiy中引用fragment,代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragment_titles"
android:name="com.android.developer.officalfragmentdemo.fragment.TitlesFragment"/>

</LinearLayout>
使用<fragment>标签引入到activity中,并且使用android:name将<fragment>标签与TitleFragment class相关联。

接下来我们需要显示article的内容,这次我们同样也是创建一个DetailsFragment继承自Fragment,与刚才不同的是我们这回需要复写onCreateView方法,并且在fragment中使用我们自定义的布局。
首先,创建一个布局文件fragment_details.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="vertical">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:gravity="center_horizontal"
android:id="@+id/article_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</ScrollView>

</LinearLayout>
由于显示的文字较多,为了能够完整的阅读这里使用了scrollview使TextView能够滑动(其布局与activity并没有什么不同)。

然后,我们需要创建一个DetailsFragment继承自Fragment,并且复写onCreateView方法,然后使用layoutinflator将布局中的view加载并返回,最后提供一个外部能够设置内容的接口用于设置文章的内容,代码如下:

/**
* Created by OnlynightZhang on 2015/7/9.
*
*/
public class DetailsFragment extends Fragment{

private TextView contentTextView;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.fragment_details, container, false);
initView( contentView );
return contentView;
}

private void initView( View contentView ){
contentTextView = (TextView)contentView.findViewById( R.id.article_content );
}

public void setArticleContent( String content ){
if ( content != null && contentTextView != null ){
contentTextView.setText( content );
}
}

public void setContentByTitle( String title ){
if ( title != null && contentTextView != null ){
Article article = getArticle( title );
if ( article != null ){
contentTextView.setText( article.getContent() );
}
}
}

private Article getArticle( String title ){
for ( Article article : Articles.ShakespeareArticles ){
if ( article.getTitle().equals( title ) ){
return article;
}
}
return null;
}
}


再次,DetailsFragment需要显示用的容器,我们这里使用一个独立的activity用于DetailsFragment的显示,其布局如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.developer.officalfragmentdemo.DetailsActivity">

<fragment
android:id="@+id/fragment_details"
android:name="com.android.developer.officalfragmentdemo.fragment.DetailsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>


activity的代码如下:

public class DetailsActivity extends AppCompatActivity {

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

String title = getIntent().getStringExtra( "title" );
if ( title != null ){
DetailsFragment detailsFragment = (DetailsFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_details);
detailsFragment.setContentByTitle( title );
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_details, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}


为了简化demo,activity间我们只传递title,我们假设title是唯一的,通过title就可以找到唯一的acticle。
最后我们来看看MainActivity中代码:

public class MainActivity extends AppCompatActivity implements TitlesFragment.TitlesItemClickListener{

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent();
            intent.setClass( this, FragmentOperationActivity.class );
            startActivity( intent );
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onItemClick(int position, String title) {
        showToast(title);
        showArticle(title);
    }

    private void showArticle( String title ){
        Intent intent = new Intent();
        intent.setClass( this, DetailsActivity.class );
        intent.putExtra( "title", title );
        startActivity( intent );
    }

    private void showToast( String text ){
        Toast.makeText( this, text, Toast.LENGTH_SHORT ).show();
    }
}


这样一个完整的Fragment使用的demo就完成了,现在你可以运行下你的demo看看了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  fragment