【Android】fragment+Viewpager+自动隐藏导航栏
16lz
2021-01-26
1、首先介绍自动fragment+Viewpager
这是效果图。 分为以下几个步骤: 1、自定义fragmentPagerAdapter,这个是Viewpager适配fragment的适配器 2、完成4个fragment的编写 3、完成activity_main.xml 4、在MainActivity中设置一下Viewpager及其监听器即可1.1自定义fragmentPage人Adapter——MainFragmentPagerAdapter
package com.ing.adapters;import java.util.ArrayList;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;/** * @date 2015-3-10 * @author DLX * 自定义FragmentPagerAdapter,用于主页的Viewpager */public class MainFragmentPagerAdapter extends FragmentPagerAdapter {private ArrayList fragmentList;public MainFragmentPagerAdapter(FragmentManager fm,ArrayList fragmentList) {super(fm);this.fragmentList = fragmentList;}@Overridepublic Fragment getItem(int i) {return fragmentList.get(i);}@Overridepublic int getCount() {return fragmentList.size();}}
其中构造方法和getItem和getCount是自定义适配器时必须要实现的方法,这里我们传入了一个list方便我们对4个fragment进行操作 1.2完成4个fragment的书写。 这里只简单的列举一个,其他3个与此差不多。我们只需要简单的实现onCreateView方法即可
package com.ing.fragments;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.example.carpool.R;public class MessageFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_message, container,false);}}
注意,这里的inflate参数的最后一个一定要是false,不然会因为布局错误(多个父组件)发生错误
1.3、完成activity_mian.xml的书写:
在这里我们处于对重复调用次数较多的代码style独立出来写了一个公共style
其中我们出于按钮点击效果的选择,创建了一个selector
<?xml version="1.0" encoding="utf-8"?>
注意,这里是RadioButton和Button的区别 在RadioButton中,它的checked的效果是可以显示出来的,就是说上面的selector的第三个item是有效的,因为RadioButton可以保持被选中的状态
但是若使用Button,就没有这个效果,即是说selector的第三个item是无效的,我们只能在监听器中通过手动更换背景图片实现。
1.4、MainActivity.java的配置 1.4.1初始化
package com.ing.activities;import java.util.ArrayList;import java.util.Timer;import java.util.TimerTask;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.Animation;import android.view.animation.LinearInterpolator;import android.view.animation.TranslateAnimation;import android.widget.Button;import android.widget.LinearLayout;import com.example.carpool.R;import com.ing.adapters.MainFragmentPagerAdapter;import com.ing.fragments.CarpoolGroupFragment;import com.ing.fragments.MessageFragment;import com.ing.fragments.MineFragment;import com.ing.fragments.SeekFragment;public class MainActivity extends FragmentActivity{//底部导航栏的4个按钮及布局private Button btn_seek, btn_carpoolgroup, btn_message, btn_mine;private LinearLayout ll;//界面中的Viewpagerprivate ViewPager viewPager;//存放Viewpager中的4个fragment的listprivate ArrayList fragmentList = new ArrayList();//自定义Viewpager切换fragment的适配器private MainFragmentPagerAdapter fragmentPagerAdapter;//等待waitDuration秒隐藏导航栏private int waitDuration = 5000;//导航栏隐藏的位移private int animDistance = 120;//标记导航栏是否被标记private boolean weatherHide=false;//动态隐藏导航栏用的Handlerprivate Handler hideHandler = new Handler();//动态隐藏导航栏的自定义Runnableprivate HideRunnable hideRunnable = new HideRunnable();//标记现在是否移除了Runnableprivate boolean hasRunnable=false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();setViewPager();}/** * 初始化 */private void init() {//初始化计时HandlerhideHandler.postDelayed(hideRunnable, waitDuration);hasRunnable=true;//初始化ViewpagerviewPager = (ViewPager) findViewById(R.id.viewpager);//初始化导航栏布局和按钮ll = (LinearLayout) findViewById(R.id.ll);btn_seek = (Button) findViewById(R.id.btn_seek);btn_carpoolgroup = (Button) findViewById(R.id.btn_carpoolgrooup);btn_message = (Button) findViewById(R.id.btn_message);btn_mine = (Button) findViewById(R.id.btn_mine);//初始化4个按钮的监听器btn_seek.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(0);}});btn_carpoolgroup.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(1);}});btn_message.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(2);}});btn_mine.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(3);}});// 四个fragment的初始化SeekFragment seekFragment = new SeekFragment();CarpoolGroupFragment carpoolGroupFragment = new CarpoolGroupFragment();MessageFragment messageFragment = new MessageFragment();MineFragment mineFragment = new MineFragment();fragmentList.add(seekFragment);fragmentList.add(carpoolGroupFragment);fragmentList.add(messageFragment);fragmentList.add(mineFragment);fragmentPagerAdapter = new MainFragmentPagerAdapter(getSupportFragmentManager(), fragmentList);}
1.4.2 设置adapter和界面改变的监听器
/** * 设置Viewpager的适配器和切换页面的监听器 */private void setViewPager() {viewPager.setAdapter(fragmentPagerAdapter);viewPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {switch (position) {case 0:btn_seek.performClick();break;case 1:btn_carpoolgroup.performClick();break;case 2:btn_message.performClick();break;case 3:btn_mine.performClick();break;}}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {}});}
2、如何实现自动隐藏底部导航栏 实现效果:若果屏幕一定时间内没有响应事件,则底部导航栏会自动隐藏,此时如果产生点击事件,那么导航栏会自动浮升上来 核心思想是translateAnimation+onTouchEvent的监听 需要注意的有两点: 一、Google并不建议使用timer来实现计时功能,这样低效且不安全。 二、Viewpager会优先使用点击事件,我们必须重新分配点击事件,不然onTouchEvent无效 对于第一点,我们使用Handler.postDelayed();解决 这样使用的时候我们通常自定义一个Runnable
/** * @date 2015-3-11 * @author DLX *自定义计时handler的Runnable类 */class HideRunnable implements Runnable{@Overridepublic void run() {hideHandler.removeCallbacks(hideRunnable);weatherHide=true;//设置动画final Animation anim = new TranslateAnimation(0,0,0,animDistance);anim.setDuration(400);anim.setFillAfter(true);anim.setInterpolator(new LinearInterpolator());ll.setAnimation(anim);ll.setVisibility(View.GONE);anim.startNow();}}
然后再在适合的地方调用即可。 对于第二个注意要点,我们可以这样处理:
/** * 防止点击事件被Viewpager吃掉,故重新分配给onTouchEvent */@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//给onTouchEvent发送事件this.onTouchEvent(ev);return super.dispatchTouchEvent(ev);}
对于onTOuchEvent的监听可以这么实现:
/** * 重写屏幕点击事件 */@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction()==MotionEvent.ACTION_DOWN) {//如果已经被隐藏了,则调用上浮动画,并且同时重启计时器(计时器在Handler中会关闭)if (weatherHide) {final Animation animUp = new TranslateAnimation(0,0,animDistance,0);animUp.setDuration(400);animUp.setFillAfter(true);ll.setAnimation(animUp);animUp.startNow();ll.setVisibility(View.VISIBLE);weatherHide=false;hideHandler.postDelayed(hideRunnable, waitDuration);}else {//如果时间不够隐藏间隔,那么重置(先删除后重启)计时器if (hasRunnable) {hideHandler.removeCallbacks(hideRunnable);hideHandler.postDelayed(hideRunnable, waitDuration);}}}return false;}
那么整个.java文件的代码是:
package com.ing.activities;import java.util.ArrayList;import java.util.Timer;import java.util.TimerTask;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.Animation;import android.view.animation.LinearInterpolator;import android.view.animation.TranslateAnimation;import android.widget.Button;import android.widget.LinearLayout;import com.example.carpool.R;import com.ing.adapters.MainFragmentPagerAdapter;import com.ing.fragments.CarpoolGroupFragment;import com.ing.fragments.MessageFragment;import com.ing.fragments.MineFragment;import com.ing.fragments.SeekFragment;public class MainActivity extends FragmentActivity{//底部导航栏的4个按钮及布局private Button btn_seek, btn_carpoolgroup, btn_message, btn_mine;private LinearLayout ll;//界面中的Viewpagerprivate ViewPager viewPager;//存放Viewpager中的4个fragment的listprivate ArrayList fragmentList = new ArrayList();//自定义Viewpager切换fragment的适配器private MainFragmentPagerAdapter fragmentPagerAdapter;//等待waitDuration秒隐藏导航栏private int waitDuration = 5000;//导航栏隐藏的位移private int animDistance = 120;//标记导航栏是否被标记private boolean weatherHide=false;//动态隐藏导航栏用的Handlerprivate Handler hideHandler = new Handler();//动态隐藏导航栏的自定义Runnableprivate HideRunnable hideRunnable = new HideRunnable();//标记现在是否移除了Runnableprivate boolean hasRunnable=false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();setViewPager();}/** * 防止点击事件被Viewpager吃掉,故重新分配给onTouchEvent */@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//给onTouchEvent发送事件this.onTouchEvent(ev);return super.dispatchTouchEvent(ev);}/** * 初始化 */private void init() {//初始化计时HandlerhideHandler.postDelayed(hideRunnable, waitDuration);hasRunnable=true;//初始化ViewpagerviewPager = (ViewPager) findViewById(R.id.viewpager);//初始化导航栏布局和按钮ll = (LinearLayout) findViewById(R.id.ll);btn_seek = (Button) findViewById(R.id.btn_seek);btn_carpoolgroup = (Button) findViewById(R.id.btn_carpoolgrooup);btn_message = (Button) findViewById(R.id.btn_message);btn_mine = (Button) findViewById(R.id.btn_mine);//初始化4个按钮的监听器btn_seek.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(0);}});btn_carpoolgroup.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(1);}});btn_message.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(2);}});btn_mine.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {viewPager.setCurrentItem(3);}});// 四个fragment的初始化SeekFragment seekFragment = new SeekFragment();CarpoolGroupFragment carpoolGroupFragment = new CarpoolGroupFragment();MessageFragment messageFragment = new MessageFragment();MineFragment mineFragment = new MineFragment();fragmentList.add(seekFragment);fragmentList.add(carpoolGroupFragment);fragmentList.add(messageFragment);fragmentList.add(mineFragment);fragmentPagerAdapter = new MainFragmentPagerAdapter(getSupportFragmentManager(), fragmentList);}/** * 设置Viewpager的适配器和切换页面的监听器 */private void setViewPager() {viewPager.setAdapter(fragmentPagerAdapter);viewPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {switch (position) {case 0:btn_seek.performClick();break;case 1:btn_carpoolgroup.performClick();break;case 2:btn_message.performClick();break;case 3:btn_mine.performClick();break;}}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {}});}/** * 重写屏幕点击事件 */@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction()==MotionEvent.ACTION_DOWN) {//如果已经被隐藏了,则调用上浮动画,并且同时重启计时器(计时器在Handler中会关闭)if (weatherHide) {final Animation animUp = new TranslateAnimation(0,0,animDistance,0);animUp.setDuration(400);animUp.setFillAfter(true);ll.setAnimation(animUp);animUp.startNow();ll.setVisibility(View.VISIBLE);weatherHide=false;hideHandler.postDelayed(hideRunnable, waitDuration);}else {//如果时间不够隐藏间隔,那么重置(先删除后重启)计时器if (hasRunnable) {hideHandler.removeCallbacks(hideRunnable);hideHandler.postDelayed(hideRunnable, waitDuration);}}}return false;}/** * @date 2015-3-11 * @author DLX *自定义计时handler的Runnable类 */class HideRunnable implements Runnable{@Overridepublic void run() {hideHandler.removeCallbacks(hideRunnable);weatherHide=true;//设置动画final Animation anim = new TranslateAnimation(0,0,0,animDistance);anim.setDuration(400);anim.setFillAfter(true);anim.setInterpolator(new LinearInterpolator());ll.setAnimation(anim);ll.setVisibility(View.GONE);anim.startNow();}}}
更多相关文章
- 使用内部(com.android.internal)和隐藏(@hide)API手记
- android 纯代码 详细编写布局文件
- Permission Denial: opening provider 隐藏的android:exported属
- android实现点击按钮切换不同的fragment布局
- Android(安卓)启动过程
- Android拍照流程
- Android实现标题显示隐藏功能
- Settings模块
- Android系统服务初始化源码分析