使用ViewPager和Fragment实现底部导航滑动重构版
2016-04-23 12:29
639 查看
本文参考自点击这里,对其进行了重构,写下思路,供自己以后思考。
实现了前面的回调监听接口,通过ViewPager方法改变当前的item值,实现自定义view时点击导航item改变页面的功能。
ViewPager使用addOnPageChangeListener进行页面的滑动监听,实现功能滑动时导航item跟着变化。
Demo下载地址 使用ViewPager和Fragment实现底部导航滑动重构版
自定义view
设置每个页面的子item
layout_tab_item.xml,每个item由一个ImageView和一个TextView组成" data-snippet-id="ext.b807b2a48a54f089d3115a5193d8ee94" data-snippet-saved="false" data-codota-status="done">[code]<?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"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true"> <ImageView android:id="@+id/tabImg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/tabText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tabImg" android:layout_centerHorizontal="true" android:text="@string/app_name" android:textColor="@android:color/white" android:textSize="16sp" /> </RelativeLayout> </RelativeLayout>
设置整个底部导航栏
layout_bottom.xml,底部导航栏由5个item组成" data-snippet-id="ext.33f6b3d8b76f926b235cd68d55819aee" data-snippet-saved="false" data-codota-status="done">[code]<?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="70dp" android:orientation="horizontal"> <include android:id="@+id/homeLayout" layout="@layout/layout_tab_item" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <include android:id="@+id/chosenLayout" layout="@layout/layout_tab_item" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <include android:id="@+id/searchLayout" layout="@layout/layout_tab_item" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <include android:id="@+id/localLayout" layout="@layout/layout_tab_item" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <include android:id="@+id/settingLayout" layout="@layout/layout_tab_item" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>
创建自定义View并配置
这里用的是bufferKnife注解功能,不懂的请移步谷歌。主要需要注意的就是需要设置很多id的BackgroundResource和TextColor,这里我把需要重复设置的地方进行了重构,知道这点就很容易看懂了。下面多了一处回调接口,主要用于实现点击item时viewpager滑动,即fragment滑动/** * 底部自定义view * Created by yyg on 2016/4/22. */ public class MyBottomLayout extends LinearLayout implements View.OnClickListener{ private Context context; private RelativeLayout homeLayout; private RelativeLayout chosenLayout; private RelativeLayout searchLayout; private RelativeLayout localLayout; private RelativeLayout settingLayout; private ICallbackListener iCallbackListener = null; public MyBottomLayout(Context context) { super(context); this.context = context; initView(); } public MyBottomLayout(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; initView(); } public MyBottomLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; initView(); } /** * 初始化 */ private void initView(){ View view = LayoutInflater.from(context).inflate(R.layout.layout_bottom, this); findView(view); initData(); initListener(); } /** * 初始化数据 */ private void initData() { setResidAndColor(0); } /** * 把所有的数据整合一起进行抽取 */ private void changeDataItem(int[] resid, int[] color) { initDataItem(homeLayout, resid[0], "首页", color[0]); initDataItem(chosenLayout, resid[1], "精选", color[1]); initDataItem(searchLayout, resid[2], "搜索", color[2]); initDataItem(localLayout, resid[3], "本地", color[3]); initDataItem(settingLayout, resid[4], "设置", color[4]); } /** * 初始化数据的抽取方法 * @param resid * @param name * @param color */ private void initDataItem(View view, int resid, String name, int color) { view.findViewById(R.id.tabImg).setBackgroundResource(resid); TextView tv = (TextView) view.findViewById(R.id.tabText); tv.setText(name); tv.setTextColor( (color == 1) ? Color.BLUE : Color.WHITE); } /** * 找到控件的方法 * * @param view */ private void findView(View view) { homeLayout = (RelativeLayout) view.findViewById(R.id.homeLayout); chosenLayout = (RelativeLayout) view.findViewById(R.id.chosenLayout); searchLayout = (RelativeLayout) view.findViewById(R.id.searchLayout); localLayout = (RelativeLayout) view.findViewById(R.id.localLayout); settingLayout = (RelativeLayout) view.findViewById(R.id.settingLayout); } /** * 控件的监听事件 */ private void initListener() { homeLayout.setOnClickListener(this); chosenLayout.setOnClickListener(this); searchLayout.setOnClickListener(this); localLayout.setOnClickListener(this); settingLayout.setOnClickListener(this); } /** * 控件的点击事件 * 点击后改变显示的图标和文字的颜色 * @param v */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.homeLayout: setResidAndColor(0); break; case R.id.chosenLayout: setResidAndColor(1); break; case R.id.searchLayout: setResidAndColor(2); break; case R.id.localLayout: setResidAndColor(3); break; case R.id.settingLayout: setResidAndColor(4); break; } //这里加入了一个接口方法,留给ViewPager去实现 //功能是点击item后viewPager也会跟着变 iCallbackListener.click(v.getId()); } /** * 设置Res和Color * @param i */ public void setResidAndColor(int i) { switch (i) { case 0: changeDataItem(setResid(new int[] {1, 0, 0, 0, 0}), new int[] {1, 0, 0, 0, 0}); break; case 1: changeDataItem(setResid(new int[] {0, 1, 0, 0, 0}), new int[] {0, 1, 0, 0, 0}); break; case 2: changeDataItem(setResid(new int[] {0, 0, 1, 0, 0}), new int[] {0, 0, 1, 0, 0}); break; case 3: changeDataItem(setResid(new int[] {0, 0, 0, 1, 0}), new int[] {0, 0, 0, 1, 0}); break; case 4: changeDataItem(setResid(new int[] {0, 0, 0, 0, 1}) , new int[] {0, 0, 0, 0, 1}); break; } } /** * 统一设置Res的地方,留有参数和返回值 * @param resid 数组,1表示选中,0表示未选中,导航页5个item都要进行判断 * @return 返回当前设置的Res,作为changeDataItem的参数 */ public int[] setResid(int[] resid) { int resHome = (resid[0] == 1) ? R.mipmap.image_tabbar_button_home_down : R.mipmap.image_tabbar_button_home; int resChosen = (resid[1] == 1) ? R.mipmap.image_tabbar_button_chosen_down : R.mipmap.image_tabbar_button_chosen; int resSearch = (resid[2] == 1) ? R.mipmap.image_tabbar_button_search_down : R.mipmap.image_tabbar_button_search; int resLocal = (resid[3] == 1) ? R.mipmap.image_tabbar_button_local_down : R.mipmap.image_tabbar_button_local; int resSetting = (resid[4] == 1) ? R.mipmap.image_tabbar_button_setting_down : R.mipmap.image_tabbar_button_setting; return new int[] {resHome, resChosen, resSearch, resLocal, resSetting}; } //初始化接口,由需要实现activity(MainActivity)调用 //通过findviewbyid获取MyBottomLayout,进行调用 public void setOnCallbackListener(ICallbackListener iCallbackListener) { this.iCallbackListener = iCallbackListener; } //自定义接口文件,click方法由调用处实现,功能是完成viewpager的滑动 public interface ICallbackListener { public void click(int id); } }
实现ViewPager和Fragment的滑动
创建fragment布局和fragment类
此处以home_fragment.xml和HomeFragment为例HomeFragment ---------------------------------- /** * 主页 * Created by yyg on 2016/4/22. */ public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.home_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } }" data-snippet-id="ext.23ec70517db3896f3cb01d5c51f22558" data-snippet-saved="false" data-codota-status="done">[code]home_fragment.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:layout_centerInParent="true" android:text="首页" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> HomeFragment ---------------------------------- /** * 主页 * Created by yyg on 2016/4/22. */ public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.home_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } }
创建activity_main.xml
记得ViewPager和刚刚自定义的MyBottomLayout都要导入类全名" data-snippet-id="ext.881937e5eb209560e3faec83f4fbf409" data-snippet-saved="false" data-codota-status="done">[code]<?xml version="1.0" encoding="utf-8"?> <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=".activity.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/myViewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/myBottomLayout" /> <com.buaa.yyg.baidupager.view.MyBottomLayout android:id="@+id/myBottomLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@mipmap/image_titlebar_background" /> </RelativeLayout>
创建BaseActivity
这一步可以省略,不过为了代码的可复用性建议加上,方便功能的添加/** * Created by yyg on 2016/4/22. */ public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(); initData(); initListener(); } @Override public void onClick(View v) { progress(); } public abstract void initView(); public abstract void initData(); public abstract void initListener(); public abstract void progress(); }
配置MainActivity
需要注意的是使用了butterknife,其他初始化数据方法都需要在其之后执行。实现了前面的回调监听接口,通过ViewPager方法改变当前的item值,实现自定义view时点击导航item改变页面的功能。
ViewPager使用addOnPageChangeListener进行页面的滑动监听,实现功能滑动时导航item跟着变化。
public class MainActivity extends BaseActivity { @Bind(R.id.myViewPager) ViewPager myViewPager; @Bind(R.id.myBottomLayout) MyBottomLayout myBottomLayout; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ButterKnife.bind(this); //super必须在最后,这样先setContentView然后super到 //BaseActivity的onCreate,之后才会调用initData等方法 //不这样会报空指针异常 super.onCreate(savedInstanceState); } @Override public void initView() { } @Override public void initData() { myViewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager())); } @Override public void initListener() { //设值注入,初始化MyBottomLayout页面的回调实例 myBottomLayout.setOnCallbackListener(new MyCallBackListener()); //ViewPager页面监听 使用add而不是set myViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { //0是静止,1是正在滑动,2是停止滑动 if (state == 2) { //设置滑动ViewPager导航同步变化 myBottomLayout.setResidAndColor(myViewPager.getCurrentItem()); } } }); } /** * 实现回调监听方法,用于改变当前item值 * 在FragmentPagerAdapter的getItem方法中切换Fragment */ private class MyCallBackListener implements MyBottomLayout.ICallbackListener { @Override public void click(int id) { switch (id) { case R.id.homeLayout: myViewPager.setCurrentItem(0); break; case R.id.chosenLayout: myViewPager.setCurrentItem(1); break; case R.id.searchLayout: myViewPager.setCurrentItem(2); break; case R.id.localLayout: myViewPager.setCurrentItem(3); break; case R.id.settingLayout: myViewPager.setCurrentItem(4); break; } } } /** * viewPager的adapter,改变当前fragment */ private class MyFragmentAdapter extends FragmentPagerAdapter { public MyFragmentAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new HomeFragment(); case 1: return new ChosenFragment(); case 2: return new SearchFragment(); case 3: return new LocalFragment(); case 4: return new SettingFragment(); } return null; } @Override public int getCount() { //一共5个页面 return 5; } } @Override public void progress() { } }
Demo下载地址 使用ViewPager和Fragment实现底部导航滑动重构版
相关文章推荐
- referrer地重要性
- html5_websocket_tomcat8
- Java web:SSH项目拷贝产生问题以及解决(getContextPath() xml hibernate等报错)
- HDU 5672 String(尺取法)
- Accessing Members of an Enclosing Class
- javascript 传参练手
- 字符串相加,可以吗?
- JS百度分享栏
- Hystrix学习(2)雪崩效应
- 我的问道游戏主题皮肤
- Myeclipse10.x破解方法
- excel批量转换日期格式,将yyyymmdd类型日期转换成yyyy-mm-dd等日期类型方法
- ROS探索总结(十六)(十七)(十八)(十九)——HRMRP机器人的设计 构建完整的机器人应用系统 重读tf 如何配置机器人的导航功能
- Swiper 中文API手册
- Linux GCC常用命令
- 树莓派 centos7 arm版本下载地址
- shell常用语法汇总
- 系统从win7更新到win10没有声音(扬声器一直显示未插入)
- 快速幂取余
- 解决404和there is no action mapped for action的问题