【Android】fragment+Viewpager+自动隐藏导航栏

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;
	}
	@Override
	public Fragment getItem(int i) {
		return fragmentList.get(i);
	}
	@Override
	public 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 {
@Override
public 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



        
    
    

注意,这里是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;
	//界面中的Viewpager
	private ViewPager viewPager;
	//存放Viewpager中的4个fragment的list
	private ArrayList fragmentList = new ArrayList();
	//自定义Viewpager切换fragment的适配器
	private MainFragmentPagerAdapter fragmentPagerAdapter;
	
	//等待waitDuration秒隐藏导航栏
	private int waitDuration = 5000;
	//导航栏隐藏的位移
	private int animDistance = 120;
	//标记导航栏是否被标记
	private boolean weatherHide=false;
	//动态隐藏导航栏用的Handler
	private Handler hideHandler = new Handler();
	//动态隐藏导航栏的自定义Runnable
	private HideRunnable hideRunnable = new HideRunnable();
	//标记现在是否移除了Runnable
	private boolean hasRunnable=false;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
		setViewPager();
	}

	/**
	 * 初始化
	 */
	private void init() {
		//初始化计时Handler
		hideHandler.postDelayed(hideRunnable, waitDuration);
		hasRunnable=true;
		//初始化Viewpager
		viewPager = (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() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(0);
			}
		});
		btn_carpoolgroup.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(1);
			}
		});
		btn_message.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(2);
			}
		});
		btn_mine.setOnClickListener(new OnClickListener() {
			
			@Override
			public 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() {
			@Override
			public 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;
				}
			}
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
			}
			@Override
			public 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{
		@Override
		public 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
	 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
	//给onTouchEvent发送事件
	this.onTouchEvent(ev);
	return super.dispatchTouchEvent(ev);
}

对于onTOuchEvent的监听可以这么实现:

/**
	 * 重写屏幕点击事件
	 */
	@Override
	public 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;
	//界面中的Viewpager
	private ViewPager viewPager;
	//存放Viewpager中的4个fragment的list
	private ArrayList fragmentList = new ArrayList();
	//自定义Viewpager切换fragment的适配器
	private MainFragmentPagerAdapter fragmentPagerAdapter;
	
	//等待waitDuration秒隐藏导航栏
	private int waitDuration = 5000;
	//导航栏隐藏的位移
	private int animDistance = 120;
	//标记导航栏是否被标记
	private boolean weatherHide=false;
	//动态隐藏导航栏用的Handler
	private Handler hideHandler = new Handler();
	//动态隐藏导航栏的自定义Runnable
	private HideRunnable hideRunnable = new HideRunnable();
	//标记现在是否移除了Runnable
	private boolean hasRunnable=false;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
		setViewPager();
	}
	/**
	 * 防止点击事件被Viewpager吃掉,故重新分配给onTouchEvent
	 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
	//给onTouchEvent发送事件
	this.onTouchEvent(ev);
	return super.dispatchTouchEvent(ev);
}
	/**
	 * 初始化
	 */
	private void init() {
		//初始化计时Handler
		hideHandler.postDelayed(hideRunnable, waitDuration);
		hasRunnable=true;
		//初始化Viewpager
		viewPager = (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() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(0);
			}
		});
		btn_carpoolgroup.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(1);
			}
		});
		btn_message.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				viewPager.setCurrentItem(2);
			}
		});
		btn_mine.setOnClickListener(new OnClickListener() {
			
			@Override
			public 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() {
			@Override
			public 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;
				}
			}
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
			}
			@Override
			public void onPageScrollStateChanged(int arg0) {
			}
		});
	}
	
	
	/**
	 * 重写屏幕点击事件
	 */
	@Override
	public 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{
		@Override
		public 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();
		}
	}
}


你可能感兴趣的:(【Android】)