ListView加Fragment实现Flyme4.0设置界面

ListView加Fragment实现Flyme4.0设置界面

使用实现了单选功能的ListView,不要问为什么不使用RecyclerView,RecyclerView真的做得不如ListView和GridView完善全面,但是RecyclerView真的是很灵活(目前发现RecyclerView有几个bug,以后再吐槽),RecyclerView也有自己的优势,这里解释一下我们为啥使用了ListView,ListView加上Fragment,点击ListView的item来切换Fragment,Fragment是可以保存状态的,使用了hide和show事务,可以根据下发的数据来创建对面的Fragment,就是创建对应的Fragment类型。下面先看看图片吧:

Flyme4.0设置界面:

ListView加Fragment实现Flyme4.0设置界面_第1张图片

我们实现的效果:

ListView加Fragment实现Flyme4.0设置界面_第2张图片

实现效果GIF:

ListView加Fragment实现Flyme4.0设置界面_第3张图片

ListView可以支持对选和单选:

tabList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);//单选
tabList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);//多选

看代码之前先看一下工程结构:
java代码:
ListView加Fragment实现Flyme4.0设置界面_第4张图片
xml文件:
ListView加Fragment实现Flyme4.0设置界面_第5张图片
要实现单选那么ListView的item的布局ViewGroup需要实现Checkable接口,下面是item_tab_list.xml

<?xml version="1.0" encoding="utf-8"?>
<com.example.bottommenudemo.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center_vertical" android:orientation="horizontal">

    <TextView  android:id="@+id/tabName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="4dp" android:clickable="false" android:layout_centerVertical="true" android:maxLines="1" android:text="标题栏" android:layout_alignParentLeft="true" android:textColor="@android:color/white" android:textSize="15sp" />

    <CheckedTextView  android:layout_width="8dip" android:layout_height="80dp" android:background="@drawable/checkbox_selector" android:gravity="center" android:layout_alignParentRight="true" android:paddingLeft="8dp" />

</com.example.bottommenudemo.CheckableRelativeLayout>

需要把CheckedTextView这个选中flag以外的控件设置为android:clickable=”false”

下面是自定义的RelativeLayout,主要是实现了Checkable接口:

package com.example.bottommenudemo;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.RelativeLayout;

/** * Created by Danxx on 2016/4/29. */
public class CheckableRelativeLayout extends RelativeLayout implements Checkable{

    private static final int CHECKABLE_CHILD_INDEX = 1;
    private Checkable child;

    public CheckableRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        child = (Checkable) getChildAt(CHECKABLE_CHILD_INDEX);
    }

    @Override
    public boolean isChecked() {
        return child.isChecked();
    }

    @Override
    public void setChecked(boolean checked) {
        child.setChecked(checked);
    }

    @Override
    public void toggle() {
        child.toggle();
    }
}

ListView的choiceMode可以在代码中设置,也可以在xml文件中设置:

 tabList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);//单选(代码实现)
 android:choiceMode="singleChoice"  //单选(xml中实现)

其余的ListView使用跟一般的ListView使用是一样的,这个时候我单击ListView的item就可以实现单选功能了。

Fragment的创建我封装了一下下,FragmentFactory.java就是用来创建对应的Fragment,需要传入FragmentBean和与ListView对应的position:

package com.example.bottommenudemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;

import java.util.HashMap;

/** * fragment build factory * Created by Danxx on 2016/4/28. */
public class FragmentFactory {
    /**fragment缓存**/
    private static HashMap<String,Fragment> fragments = new HashMap<String, Fragment>();

    public static Fragment buildFragment(FragmentBean data ,int pos){
        Fragment fragment = null;
        String id = data.getID();
        String name = data.getName();
        int position = data.getPosition();
        String url = data.getUrl();

        fragment = fragments.get(String.valueOf(pos));
        if(fragment != null){
            return fragment;
        }

        if(id.equalsIgnoreCase(Common.BACKGROUND)){
            fragment = new FragmentSetBackground();
        }else if(id.equalsIgnoreCase(Common.RECOMMEND)){
            fragment = new FragmentSetRecommend();
        }else if(id.equalsIgnoreCase(Common.SCREENSAVER)){
            fragment = new FragmentSetScreensaver();
        }else if(id.equalsIgnoreCase(Common.ABOUT)){
            fragment = new FragmentSetAbout();
        }

        Bundle bundle = new Bundle();
        bundle.putString("id" ,id);
        bundle.putString("name" ,name);
        bundle.putInt("position", position);
        bundle.putString("url" , url);

        if(fragment != null){
            //传递简单的参数
            fragments.put(String.valueOf(pos), fragment);
            fragment.setArguments(bundle);
        }
        return fragment;

    }

}

直接看MainActivity的代码:

package com.example.bottommenudemo;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    private ListView tabList;
    private List<FragmentBean> fragmentData = new ArrayList<FragmentBean>();
    private MyAdapater mAdapter;
    private int lastPosition = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_2_main);
        Log.d("danxx", "onCreate--->");
        tabList = (ListView) findViewById(R.id.tabList);
        /************************填充假数据,可以根据服务器下发的数据来初始化数据(一定得给出模板类型layout_code)*************************/
        FragmentBean backGround = new FragmentBean(Common.BACKGROUND,0,"背景0","http://www.dusa.com/da/index.jsp");
        fragmentData.add(backGround);
        FragmentBean recommend = new FragmentBean(Common.RECOMMEND,1,"推荐>1","http://www.dusa.com/food/list.jsp");
        fragmentData.add(recommend);
        FragmentBean screensaver = new FragmentBean(Common.SCREENSAVER,2,"背景>2" ,"http://www.meitu.com/pic/con.jsp");
        fragmentData.add(screensaver);
        FragmentBean about = new FragmentBean(Common.ABOUT,3,"关于>3","http://www.alibaba.com/good/index.php");
        fragmentData.add(about);

        FragmentBean backGround2 = new FragmentBean(Common.BACKGROUND,4,"背景>4","http://www.dusa.com/da/index.jsp");
        fragmentData.add(backGround2);
        FragmentBean about2 = new FragmentBean(Common.ABOUT,5,"关于>5","http://www.alibaba.com/good/index.php");
        fragmentData.add(about2);
        FragmentBean recommend2 = new FragmentBean(Common.RECOMMEND,6,"推荐>6","http://www.dusa.com/food/list.jsp");
        fragmentData.add(recommend2);
        FragmentBean screensaver2 = new FragmentBean(Common.SCREENSAVER,7,"背景>7" ,"http://www.meitu.com/pic/con.jsp");
        fragmentData.add(screensaver2);
        FragmentBean about3 = new FragmentBean(Common.ABOUT,8,"关于>8","http://www.alibaba.com/good/index.php");
        fragmentData.add(about3);


        mAdapter = new MyAdapater(this , fragmentData);
        tabList.setAdapter(mAdapter);
        tabList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        mAdapter.notifyDataSetChanged();
        /**根据用户点击来切换fragment**/
        tabList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("danxx" ,"position-->"+position);
                if(lastPosition == position){
                    return;
                }
                if(lastPosition != -1){
                    Fragment fromFragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(lastPosition));
                    if(fromFragment==null){
                        fromFragment = buildFragment(lastPosition);
                    }
                    Fragment toFragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(position));
                    if(toFragment == null){
                        toFragment = buildFragment(position);
                    }
                    switchContent(fromFragment ,lastPosition ,toFragment ,position);

                }else{
                    /*第一次显示fragment*/
                    getSupportFragmentManager().beginTransaction().
                        add(R.id.content ,FragmentFactory.buildFragment(mAdapter.getItemData(position) ,position) ,String.valueOf(position)).commit();
                }
                lastPosition = position;
            }
        });
    }

    public Fragment buildFragment(int position){
        /**根据模板类型layout_code的不同来创建对应的fragment**/
        return FragmentFactory.buildFragment(mAdapter.getItemData(position) ,position);
    }

    /** * 切换显示的fragment * @param fromFragment * @param fromPos * @param toFragment * @param toPos */
    public void switchContent(Fragment fromFragment ,int fromPos, Fragment toFragment ,int toPos) {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (!toFragment.isAdded()) {    // 先判断是否被add过
            transaction.hide(fromFragment).add(R.id.content, toFragment ,String.valueOf(toPos)).commit(); // 隐藏当前的fragment,add下一个到Activity中
        } else {
            transaction.hide(fromFragment).show(toFragment).commit(); // 隐藏当前的fragment,显示下一个
        }
    }

    class MyAdapater extends BaseAdapter{

        private List<FragmentBean> mData;
        private Context mContext;

        public MyAdapater(Context context , List<FragmentBean> data){
            this.mContext = context;
            this.mData = data;
        }

        @Override
        public int getCount() {
            return mData.size();
        }
        @Override
        public Object getItem(int position) {
            return mData.get(position);
        }

        public FragmentBean getItemData(int position){
            return mData.get(position);
        }

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

        /** * 数据不会很多,所以没有使用ViewHolder复用 * @param position * @param convertView * @param parent * @return */
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            Log.d("danxx" ,"getView_position-->"+position);
            final View view =  LayoutInflater.from(mContext).inflate(R.layout.item_tab_list , null);

            TextView tabName = (TextView) view.findViewById(R.id.tabName);

            tabName.setText(mData.get(position).getName());

            return view;
        }


    }
}

MainActivity.java需要留意的就是,我们在切换Fragment的时候并没有把所有的Fragment都找到,然后hide掉,我觉得这样真的很没有必要,耗时耗力,还显得很蠢,我使用了switchContent方法来做这个操作,从一个Fragment切换到另一个Fragment,就直接是hide现在看到的Fragment,show我们需要的Fragment,这样我们切换Fragment就总是对两个Fragment做处理,是不是简洁了很多?

    /** * 切换显示的fragment * @param fromFragment * @param fromPos * @param toFragment * @param toPos */
    public void switchContent(Fragment fromFragment ,int fromPos, Fragment toFragment ,int toPos) {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (!toFragment.isAdded()) {    // 先判断是否被add过
            transaction.hide(fromFragment).add(R.id.content, toFragment ,String.valueOf(toPos)).commit(); // 隐藏当前的fragment,add下一个到Activity中
        } else {
            transaction.hide(fromFragment).show(toFragment).commit(); // 隐藏当前的fragment,显示下一个
        }
    }

完整的代码请看GitHub:FragmentSwitchDemo

你可能感兴趣的:(Fragment)