ListView加Fragment实现Flyme4.0设置界面
来源:互联网 发布:c语言入门经典 编辑:程序博客网 时间:2024/04/30 22:43
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设置界面:
我们实现的效果:
实现效果GIF:
ListView可以支持对选和单选:
tabList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);//单选tabList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);//多选
看代码之前先看一下工程结构:
java代码:
xml文件:
要实现单选那么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
- ListView加Fragment实现Flyme4.0设置界面
- 实现iphone设置界面的listview控件
- Fragment实现android的设置界面切换效果
- 使用viewpager加fragment切换界面
- android 自定义listview实现仿微信/QQ设置界面的开发
- Fragment下listview item设置fragment,
- Android常用控件之Fragment仿Android4.0设置界面
- ViewPager+Fragment实现界面滑动
- ViewPager + Fragment 实现类微信界面
- RadioGroup+Fragment实现界面切换
- [Android源码分析]从蓝牙界面看设置中fragment的实现
- 使用Fragment兼容手机平板-之设置主界面的模仿简单实现
- 使用ListView实现聊天界面
- android-ListView实现复杂界面
- 用Android Studio实现ViewPager加Fragment
- 用FragmentTabHost加Fragment实现底部菜单
- ListFragment,Fragment+ListView,ListActivity,Activity+ListView方法实现listview效果
- ToolBar加DrawerLayout加Fragment实现侧滑菜单
- 【LeetCode】Majority Element 解题报告
- 以太网之物理层
- HDU-4597 Play Game (区间DP)
- 【Unity3d】浅谈异步加载场景
- 【世界是自己的,与他人毫无关系】--杨绛
- ListView加Fragment实现Flyme4.0设置界面
- 课堂笔记之自定义线程池
- pathspec did not match any file known to git
- POJ_1084_SquareDestroyer(DancingLinksX重复覆盖)
- L1 L2正则化
- python错误
- 解决ajax不能访问本地文件(利用js跨域原理)
- Node.js
- readLine方法的简单练习,回答2016-04-27 的帖子的问题