Android开发之实用FragmentLayout+fragment实现新浪微博的四个主页面

  发布日期:   2017-06-01
  最新修改:   2020-05-28
  阅读次数:   17 次

在使用之前如果还没用过fragment的同学可以先了解下fragment的相关知识

1、Fragment:

Fragment可以做为Activity的一个界面的一个组成部分,Activity的界面可以完全由不同的Fragment组成,注意的是Fragment拥有自己的生命周期和接收、处理用户的事件,这样就不必在Activity写一堆控件的事件处理的代码了。更为重要的是,你可以动态的添加、替换和移除某个Fragment。当然,你可以把fragment当成普通的控件一样放在activity的xml布局文件中。

Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:

可以看到Fragment比Activity多了几个额外的生命周期回调方法: onAttach(Activity) 当Fragment与Activity发生关联时调用。 onCreateView(LayoutInflater, ViewGroup,Bundle) 创建该Fragment的视图 onActivityCreated(Bundle) 当Activity的onCreate方法返回时调用 onDestoryView() 与onCreateView想对应,当该Fragment的视图被移除时调用 onDetach() 与onAttach相对应,当Fragment与Activity关联被取消时调用

注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,

参考自:http://blog.csdn.net/lmj623565791/article/details/37970961/

http://www.cnblogs.com/shaweng/p/3918985.html

FragmentManager:你可以把FragmentManager想象成管理一系列的fragment的隐藏展示的一个类

接下来我们就来实现四个页面

最终效果:

第一步:布局MainActivity的布局文件

首先,我们在main_activity.xml中使用fragmentlayout来动态的装载我们要动态切换的四个fragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="guanaj.com.weibo.MainActivity">

    <FrameLayout
        android:id="@+id/root_fragment_layout"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="match_parent" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#cccccc" />

    <RadioGroup
        android:id="@+id/radiogroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
        android:paddingTop="10dp">

        <RadioButton
            android:id="@+id/radiobutton_home"
            style="@style/main_radiobutton_stype"
            android:checked="true"
            android:drawableTop="@drawable/rb_select_home"
            android:text="主页" />

        <RadioButton
            android:id="@+id/radiobutton_message"
            style="@style/main_radiobutton_stype"
            android:drawableTop="@drawable/rb_select_message"
            android:text="消息" />

        <RadioButton
            android:id="@+id/radiobutton_post"

            style="@style/main_radiobutton_stype"
            android:text="发布" />

        <RadioButton
            android:id="@+id/radiobutton_discover"
            style="@style/main_radiobutton_stype"

            android:drawableTop="@drawable/rb_select_discover"
            android:text="发现" />

        <RadioButton
            android:id="@+id/radiobutton_profile"
            style="@style/main_radiobutton_stype"

            android:drawableTop="@drawable/rb_select_profile"
            android:text="我" />

    </RadioGroup>
</LinearLayout>

可以看到,底部我就先用RadioGroup+RadioButton实现,中间用一个View来实现一个灰色的分割线

底部按钮的样式为了统一管理,我们可以把他公共的样式抽取出来放到res/values/styles.xml文件中

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="main_radiobutton_stype">
        <item name="android:gravity">center</item>
        <item name="android:button">@null</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_weight">1</item>
        <item name="android:layout_height">wrap_content</item>
    </style>

</resources>

底部按钮的选中和不选中状态我们可以是用select选择器来实现,代码分别如下

rb_select_home.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/tabbar_home_selected" android:state_checked="true"/>
    <item android:drawable="@drawable/tabbar_home" android:state_checked="false"/>
</selector>

state_checked='true'表示被选中时显示的图片,其余三个类似

好的,布局文件准备好了,接下来我们要来准备四个fragment

第二步:实现四个Fragment

1、HomeFragment.java

package guanaj.com.weibo.pager;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import guanaj.com.weibo.R;

/**
 * Created by guanaj on 2017/2/14.
 */

public class HomeFragment extends Fragment {

    public Activity mActivity;
    public LayoutInflater mInflater;

    @Override
    public void onAttach(Context context) {

        super.onAttach(context);

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //activity创建时回掉,在这里获去依赖的activity对象
        mActivity = getActivity();

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        mInflater = inflater;//用来将xml文件实例化成View的类实例
        //在HomeFragment的xml文件渲染成view。
        View rootView = mInflater.inflate(R.layout.fragment_home,null);
        //返回的View即为fragment要显示的View
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //fragment依赖的activity创建完成时回掉,一般在这里做fragment页面数据的初始化
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onDetach() {

        super.onDetach();
    }

}

2、HomeFragment的布局文件为

R.layout.fragment_home

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    /**
    * Created by guanaj on .
    */
    <TextView
        android:text="主页"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

2、MessageFragment.java

package guanaj.com.weibo.pager;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import guanaj.com.weibo.R;

/**
 * Created by guanaj on 2017/2/14.
 */

public class MessageFragment extends Fragment {

    public Activity mActivity;
    public LayoutInflater mInflater;

    @Override
    public void onAttach(Context context) {

        super.onAttach(context);

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //activity创建时回掉,在这里获去依赖的activity对象
        mActivity = getActivity();

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        mInflater = inflater;//用来将xml文件实例化成View的类实例
        //在HomeFragment的xml文件渲染成view。
        View rootView = mInflater.inflate(R.layout.fragment_message,null);

        //返回的View即为fragment要显示的View
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //fragment依赖的activity创建完成时回掉,一般在这里做fragment页面数据的初始化
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onDetach() {

        super.onDetach();
    }

}

2、MessageFragment的布局文件

R.layout.fragment_message

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    /**
    * Created by guanaj on .
    */
    <TextView
        android:text="消息"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

其余两个类似

第三步:在MainActivity中动态的根据底部按钮的选中状态切换要显示的fragment

MainActivity.java的代码为:

package guanaj.com.weibo;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.FrameLayout;
import android.widget.RadioGroup;
import java.util.ArrayList;
import guanaj.com.weibo.pager.DiscoverFragment;
import guanaj.com.weibo.pager.HomeFragment;
import guanaj.com.weibo.pager.MessageFragment;
import guanaj.com.weibo.pager.ProfileFragment;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private ArrayList<Fragment> fragmentList = new ArrayList<>();

    private RadioGroup radioGroup;
    private FragmentManager fragmentManager;

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

    }
    private void initViews() {
        //1、获取main_activity中的控件的实例化对象
        radioGroup = (RadioGroup) findViewById(R.id.radiogroup);
        //2、获取FragmentManager
        /*注意倒入的fragmentManager,如果你的fragment是android.support.v4.app包中的,
        你倒入的fragmentManager也要试v4v 包的,
        我这里的fragment是import android.app.Fragment; 所以我导入的fragmentManager也是android.app包下面的
        * */
        /*如果是v4包的要用this.getSupportFragmentManager();*/
        fragmentManager = this.getFragmentManager();

    }

    private void initEvent() {
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.radiobutton_home: {
                        setCurrentFragment(0);
                        break;
                    }
                    case R.id.radiobutton_message: {
                        setCurrentFragment(1);
                        break;
                    }
                    case R.id.radiobutton_discover: {
                        setCurrentFragment(2);
                        break;
                    }
                    case R.id.radiobutton_profile: {
                        setCurrentFragment(3);
                        break;
                    }
                    case R.id.radiobutton_post:{

                        break;
                    }
                    default: {

                    }

                }
//
            }
        });

    }

    private void initData() {
        /*3、数据的准备*/
        HomeFragment homeFragment = new HomeFragment();
        fragmentList.add(homeFragment);
        MessageFragment messageFragment = new MessageFragment();
        fragmentList.add(messageFragment);
        DiscoverFragment discoverFragment = new DiscoverFragment();
        fragmentList.add(discoverFragment);
        ProfileFragment profileFragment = new ProfileFragment();
        fragmentList.add(profileFragment);
        //默认显示第1个也就是fragmentList.get(0)
        setCurrentFragment(0);

    }

    /**
     * 显示fragment
     * @param index
     */
    private void setCurrentFragment(int index){
        //3 通过fragmentmanager获取fragment的事务管理对象
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //4获取要显示的fragment
        Fragment fragment = fragmentList.get(index);
        //5、将要显示的fragment放入FragmentLayout中
        fragmentTransaction.replace(R.id.root_fragment_layout, fragment);
        //6、提交事务,确定显示
        fragmentTransaction.commit();
    }

}

   转载规则

《Android开发之实用FragmentLayout+fragment实现新浪微博的四个主页面字》GajAngels 采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。