先上一张图,看懂这张图后,才可以看下面的内容。 这张图的意思就是什么东西里面又包含了什么东西的意思,代码其实只是如何“剥”出每一层。

下面开始整代码:

第一步:新建一个安卓项目,它会自动生成MainActivity.java和activity_main.xml, 请不要改名字;

第二步:新建一个fragment,取名为MainFragment,它会自动生成MainFragment.java和main_fragemnt.xml,请不要做任何修改;

第三步:新建一个fragment,取名为MenuFragment,它会自动生成MenuFragment.java和menu_fragemnt.xml,请不要做任何修改;

第四步:修改activity_main.xml文件的内容为:

<?xml version="1.0" encoding="utf-8"?>
<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="com.jintingbo.myapplication17.MainActivity">

    <FrameLayout
        android:id="@+id/fl_menu"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:background="#20ff0000"
        android:layout_height="match_parent"/>
    <FrameLayout
        android:id="@+id/fl_main"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:background="#2500ff00"
        android:layout_height="match_parent"/>
</LinearLayout>

把它改为线性布局,添加两个碎片,做菜单的碎片fl_menu的宽度占屏幕宽度的1/3,做内容的碎片fl_main点屏幕宽度的2/3;

注意上面是两个FrameLayout帧布局,而不是两个Fragment碎片。 用FrameLayout的原因,相当于是先做一个模板,程序启动后,还要用两个碎片把它们替换下来。

第五步:修改MainActivity.java中的文件内容为:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MenuFragment menuFragment = new MenuFragment();
        final MainFragment mainFragment  = new MainFragment();

        //用碎片替换帧布局只能用事务处理
        getSupportFragmentManager().beginTransaction().replace(R.id.fl_menu, menuFragment, "menuFragment").commit();
        getSupportFragmentManager().beginTransaction().replace(R.id.fl_main, mainFragment, "mainFragment").commit();
        menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
            @Override
            public void dataTransmission(String data) {
                mainFragment.setData(data);
            }
        });
    }
}

final MainFragment mainFragment = new MainFragment();  为什么要加final,是因为下面的mainFragment.setData(data);必须要求mainFragmint是常量才可以运行。

getSupportFragmentManager().beginTransaction().replace(R.id.fl_menu, menuFragment, "menuFragment").commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fl_main, mainFragment, "mainFragment").commit();
        这两句是将原来Activity中有的fragment全部清除后,再添加现在的menuFragment和mainFragment,它的意思是,你用哪个fragment,就把其它的全部清了,这样不干扰。   这里为什么是用事务的replace()呢?因为事务可以后退, 如果不是事务的replace()你就后退不成,因为原来fragmetn全部被清除了。

replace()的第三个参数,第一个是被替换的布局ID,第二个是替换的对象,第三个是有待去查资料。

menuFragment.setOnDataTransmissionListener()是执行自定义的监听事件,这与Button的点击事件不一样,因为fragment不确定,所以监听什么也是不确定的,因此要自定义。 具体代码要看MenuFragment.java。

第六步:修改menu_fragemnt.xml中的内容

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/lv_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

在这个碎片中添加一个ListView控件,仅此而己

第七步:在layout中新建一个menu_fragemnt_item.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_menu_item"
        android:layout_width="match_parent"
        android:gravity="center_vertical"
        android:textColor="#000"
        android:layout_height="40dp" />
</RelativeLayout>

        为什么要加这个“额外的"XML呢?因为ListView中包含各”条目",而各条目的内部组成实际上是一个TextView.所以就用这个TextView代表所有条目的中的TextView。这个XML文件没有与它相对应的类。

第八步:修改MenuFragment.java为如下内容

/**
 * 左侧的菜单Fragment
 * Created by Jun&Hui on 2016/10/9.
 */
public class MenuFragment extends Fragment {
    List<String> mDatas = new ArrayList<>();
    private OnDataTransmissionListener mListener;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //求碎片
        View menuView = View.inflate(getActivity(), R.layout.menu_fragemnt, null);
        //准备显示值
        mDatas.add("新闻1");
        mDatas.add("新闻2");
        mDatas.add("新闻3");
        mDatas.add("新闻4");
        mDatas.add("新闻5");
        //求碎片中的ListView控件
        final ListView lv = (ListView) menuView.findViewById(R.id.lv_menu);
        //用适配器设置显示值和求一些其它的值
        lv.setAdapter(new BaseAdapter() {
            @Override
            public int getCount() {
                return mDatas.size();
            }

            @Override
            public Object getItem(int position) {
                return mDatas.get(position);
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                //求条目,因为ListView中的条目与menu_fragment_item的表现形式是样
                //其实就是获取menu_fragment_item.xml
                View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.menu_fragemnt_item, parent, false);
                //求条目中的文本
                TextView tv = (TextView) contentView.findViewById(R.id.tv_menu_item);

                tv.setText(mDatas.get(position));

                /**
                 * 需求:点击对应的条目,将条目的内容发送到MainFragment中的Button上,更改Button名称(即进行一个数据传递)
                 */

                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        /**
                         * 方法三:使用第三方开源框架EventBus
                         */
                        EventBus.getDefault().post(mDatas.get(position));
                    }
                });

                return contentView;
            }
        });

        return menuView;
    }

    //接口回调的方法
    public interface OnDataTransmissionListener {
        public void dataTransmission(String data);
    }

    public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
        this.mListener = mListener;
    }
}

弄懂上面的代码,基本上就把整个程序就弄懂了,下面我慢慢道来:

List<String> mDatas = new ArrayList<>(); 这一句的目的就是为了给ListView条目设置显示值的,比如第一条是新闻1,第二条是新闻2....,   下面的mDatas.add("新闻1");等几条语句就是为它设置显示值。 

private OnDataTransmissionListener mListener;  这是一条事务监听对象; 

onCreateView()是fragmet生命周期的函数, 它是管fragment界面上的东西的;

View menuView = View.inflate(getActivity(), R.layout.menu_fragemnt, null);这一句是获取Activiti中的菜单(menu_fragemnt)视图, 第一个参数getActivity()表示求本fragment的宿主。

final ListView lv = (ListView) menuView.findViewById(R.id.lv_menu);这一句表示再从上一句所求的菜单视图中求出ListView控件。

lv.setAdapter(new BaseAdapter()); 这一句表示是给ListView设置适配器,目的是要给ListView设置显示值和对ListView进行监听,
这里的适配器是使用BaseAdapter。
得到lv(lv就是ListView控件)后,还要再进一点得到其中的“条目”其它语言叫Item,这个“条目”要在
public View getView(int position, View convertView, ViewGroup parent){}中去求,

View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.menu_fragemnt_item, parent, false);这一句就是求条目。

TextView tv = (TextView) contentView.findViewById(R.id.tv_menu_item);这一句表示求条目中的TextView;

tv.setText(mDatas.get(position));这一句表示为条目中的TextView赋值,就是在条目上显示标题。

lv.setOnItemClickListener(new AdapterView.OnItemClickListener());这一句表示ListView的监听事件;从下面的onItemClick可以看出它监听的是点击事件。

EventBus.getDefault().post(mDatas.get(position));这一句表示用EventBus框架,发送一个数据出去。 EventBus是第三方框架,在使用时要加依赖,具体位置是在build.gradle(Modul:app)中的
dependencies {
    ...
    implementation 'org.greenrobot:eventbus:3.0.0'
    ...
}

onCreateView()是返回的碎片, getView()是返回的“条目”, 

后面的代码:
//接口回调的方法
public interface OnDataTransmissionListener {
    public void dataTransmission(String data);
}

public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
    this.mListener = mListener;
}
是与MainActivity.java中的事务监听事件密切相关的。public interface OnDataTransmissionListener{}是定义的一个内部接口。

第九步:修改MainFragment.java文件的内容为:(注释都写清楚了,就不另外再解释)

public class MainFragment extends Fragment {
    //有一个TextView
    private TextView textView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //得到主界面中的main碎片
        View mainView = View.inflate(getActivity(), R.layout.main_fragemnt, null);
        //得到碎片中的textView
        textView=(TextView)mainView.findViewById(R.id.textView);
        //注册第三方框架
        EventBus.getDefault().register(this);
        return mainView;
    }

    @Subscribe
    public void onEvent(String data) {
        textView.setText(data);
    }
    public void setData(String string) {
        textView.setText(string);
    }

    //退出时要撤销第三方框架
    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

最后结果:

标题

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐