多种多样的App主界面Tab实现方法——单独利用ViewPager实现Tab
2016-03-09 21:07
453 查看
视频地址:http://www.imooc.com/video/5901
首先,还是先展示一下项目的目录结构:
我这里着重讲实现的过程,所以大部分布局文件不会很详细的贴出来,当然,依照惯例,会在文章的末尾放出我的源码,需要图片资源的可以去源码里面找,而且需要注意的是,我的源码是基于Android Studio的。
对了,还有必要提出一下,在视频处提供的源码中的图片中,有几张.9.png格式的图片并不是真正的.9.png图片,而是.png格式的,因此在运行的时候会导致无法成功,所以我直接改成了.png格式的(为了偷个懒,就没有去修改成真正的.9.png格式)。
还是先对activity_main布局文件讲解一下,其中
这里需要注意的是ViewPager,在设置属性的时候,有如下代码:
而不是平常的
这是因为主布局为线性布局(
(因为
在布局文件中,还有为tab0X的四个布局文件,内容简单且相似(这里展示的是tab01):
四个布局简单且相似,是用于添加到ViewPager中从而根据Tab显示相应的内容的。
然后就是代码的实现了:
为了单独利用一个ViewPager来实现所需的功能,需要给ViewPager设置一个PagerAdapter类型的适配器,而PagerAdapter中需要用到一个存放布局的
在本次的实现中,需要注意三点:
1、AppCompatActivity隐藏标题时为
而非
2、在实现点击Tab的时候,如果不加注意,会出现一个Bug:
在点击Tab的ImageButton时,VierPager是不会有对应的切换的
产生的原因:
每个Tab都是一个LinearLayout,而每个LinearLayout中又有一个ImageButton,当点击ImageButton的位置时,点击事件首先到LinearLayout上,然后LinearLayout做出判断,发现在自己的内部有一个ImageButton可以解决点击事件,所以会把点击事件交给ImageButton处理,但是ImageButton又没有设置点击事件,所以不会有任何的相应。
解决方法一:给每个ImageButton都设置点击事件;
解决方法二:使LinearLayout知道ImageButton不能处理点击事件,从而自己处理,所以需要给ImageButton设置android:clickable=”false”属性,使ImageButton成为不可点击的。
3、当从第一个Tab对应的布局切换到第四个Tab对应的布局的时候,实际上是从第四个切换到第三个,然后切换到第二个,最后才是切换到第一个,反之亦然,简单的说就是当需要切换到间隔的Tab时,需要经过夹在中间的Tab,只不过切换的速度比较快,需要用慢动作才是看清楚。当需要切换的Tab多的时候,会带来不好的体验感!
在我具体的操作的过程中,不知道为什么,完成代码后运行App时,最开始ViewPager就停在最后一个Tab对应的布局上,且无法滑动,点击下面的tab的时候,只有“微信”和“朋友”两个在点击之后使ViewPager切换到相应的tab0X布局,而“通讯录”和“设置”两个Tab能够相应点击事件,但是ViewPager无法切换到相应的tab0X布局后来在修改了一下Compile Sdk Version和Build Tools Version之后(本来是6.0和23.0.2,然后换成低版本的,出现了Cannot resolve symbol ‘R’的问题,就又换了回去,之后上述的问题就变正常了)
源码:http://download.csdn.net/download/qq_22804827/9457018
首先,还是先展示一下项目的目录结构:
我这里着重讲实现的过程,所以大部分布局文件不会很详细的贴出来,当然,依照惯例,会在文章的末尾放出我的源码,需要图片资源的可以去源码里面找,而且需要注意的是,我的源码是基于Android Studio的。
对了,还有必要提出一下,在视频处提供的源码中的图片中,有几张.9.png格式的图片并不是真正的.9.png图片,而是.png格式的,因此在运行的时候会导致无法成功,所以我直接改成了.png格式的(为了偷个懒,就没有去修改成真正的.9.png格式)。
还是先对activity_main布局文件讲解一下,其中
top是顶部显示“微信”一栏的布局,
bottom是显示底部四个Tab的布局(每个Tab是一个
LinearLayout,内部包含一个ImageButton和一个TextView),而中间的空白区域部分是一个ViewPager,是为了放置
tab0X布局的。
这里需要注意的是ViewPager,在设置属性的时候,有如下代码:
android:layout_height="0dp" android:layout_weight="1"
而不是平常的
android:layout_height="match_parent"
这是因为主布局为线性布局(
android:layout_weight只在线性布局中起作用),如果将ViewPager的
android:layout_height设置为
match_parent,就会把bottom布局的空间挤掉。
(因为
android:layout_weight是按比例分配所有控件所占空间后的剩余空间,关于
android:layout_weight可以去这儿学习一下)
在布局文件中,还有为tab0X的四个布局文件,内容简单且相似(这里展示的是tab01):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="This is WeiXin Tab" android:textStyle="bold" android:textSize="30sp"/> </LinearLayout>
四个布局简单且相似,是用于添加到ViewPager中从而根据Tab显示相应的内容的。
然后就是代码的实现了:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private ViewPager mViewPager; private PagerAdapter mAdapter; private List<View> mViews = new ArrayList<View>(); //TAB private LinearLayout mTabWeixin; private LinearLayout mTabFrd; private LinearLayout mTabAddress; private LinearLayout mTabSetting; private ImageButton mWeixinImg; private ImageButton mFrdImg; private ImageButton mAddressImg; private ImageButton mSettingImg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportActionBar().hide();//隐藏标题栏 initView(); initEvents(); } private void initEvents() { mTabWeixin.setOnClickListener(this); mTabFrd.setOnClickListener(this); mTabAddress.setOnClickListener(this); mTabSetting.setOnClickListener(this); //监听Page的变化,在这里需要实现onPageSelected()方法中的逻辑 mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { int currentItem = mViewPager.getCurrentItem(); resetImg(); switch (currentItem) { case 0: mWeixinImg.setImageResource(R.drawable.tab_weixin_pressed); break; case 1: mFrdImg.setImageResource(R.drawable.tab_find_frd_pressed); break; case 2: mAddressImg.setImageResource(R.drawable.tab_address_pressed); break; case 3: mSettingImg.setImageResource(R.drawable.tab_settings_pressed); break; } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels){} @Override public void onPageScrollStateChanged(int state){} }); } private void initView() { mViewPager = (ViewPager) findViewById(R.id.id_viewpager); // tabs mTabWeixin = (LinearLayout) findViewById(R.id.id_tab_weixin); mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd); mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address); mTabSetting = (LinearLayout) findViewById(R.id.id_tab_settings); // ImageButton mWeixinImg = (ImageButton) findViewById(R.id.id_tab_weixin_img); mFrdImg = (ImageButton) findViewById(R.id.id_tab_frd_img); mAddressImg = (ImageButton) findViewById(R.id.id_tab_address_img); mSettingImg = (ImageButton) findViewById(R.id.id_tab_settings_img); LayoutInflater mInflater = LayoutInflater.from(this); mViews.add(mInflater.inflate(R.layout.tab01, null)); mViews.add(mInflater.inflate(R.layout.tab02, null)); mViews.add(mInflater.inflate(R.layout.tab03, null)); mViews.add(mInflater.inflate(R.layout.tab04, null)); mAdapter = new PagerAdapter() { @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mViews.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { View view = mViews.get(position); container.addView(view); return view; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getCount() { return mViews.size(); } }; mViewPager.setAdapter(mAdapter); } @Override public void onClick(View v) { resetImg(); switch (v.getId()) { case R.id.id_tab_weixin: mViewPager.setCurrentItem(0); mWeixinImg.setImageResource(R.drawable.tab_weixin_pressed); break; case R.id.id_tab_frd: mViewPager.setCurrentItem(1); mFrdImg.setImageResource(R.drawable.tab_find_frd_pressed); break; case R.id.id_tab_address: mViewPager.setCurrentItem(2); mAddressImg.setImageResource(R.drawable.tab_address_pressed); break; case R.id.id_tab_settings: mViewPager.setCurrentItem(3); mSettingImg.setImageResource(R.drawable.tab_settings_pressed); break; default: break; } } /** * 将所有的图片切换为暗色的 */ private void resetImg() { mWeixinImg.setImageResource(R.drawable.tab_weixin_normal); mFrdImg.setImageResource(R.drawable.tab_find_frd_normal); mAddressImg.setImageResource(R.drawable.tab_address_normal); mSettingImg.setImageResource(R.drawable.tab_settings_normal); } }
为了单独利用一个ViewPager来实现所需的功能,需要给ViewPager设置一个PagerAdapter类型的适配器,而PagerAdapter中需要用到一个存放布局的
List<View>。
在本次的实现中,需要注意三点:
1、AppCompatActivity隐藏标题时为
setContentView(R.layout.activity_main); getSupportActionBar().hide();
而非
requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main);
2、在实现点击Tab的时候,如果不加注意,会出现一个Bug:
在点击Tab的ImageButton时,VierPager是不会有对应的切换的
产生的原因:
每个Tab都是一个LinearLayout,而每个LinearLayout中又有一个ImageButton,当点击ImageButton的位置时,点击事件首先到LinearLayout上,然后LinearLayout做出判断,发现在自己的内部有一个ImageButton可以解决点击事件,所以会把点击事件交给ImageButton处理,但是ImageButton又没有设置点击事件,所以不会有任何的相应。
解决方法一:给每个ImageButton都设置点击事件;
解决方法二:使LinearLayout知道ImageButton不能处理点击事件,从而自己处理,所以需要给ImageButton设置android:clickable=”false”属性,使ImageButton成为不可点击的。
3、当从第一个Tab对应的布局切换到第四个Tab对应的布局的时候,实际上是从第四个切换到第三个,然后切换到第二个,最后才是切换到第一个,反之亦然,简单的说就是当需要切换到间隔的Tab时,需要经过夹在中间的Tab,只不过切换的速度比较快,需要用慢动作才是看清楚。当需要切换的Tab多的时候,会带来不好的体验感!
在我具体的操作的过程中,不知道为什么,完成代码后运行App时,最开始ViewPager就停在最后一个Tab对应的布局上,且无法滑动,点击下面的tab的时候,只有“微信”和“朋友”两个在点击之后使ViewPager切换到相应的tab0X布局,而“通讯录”和“设置”两个Tab能够相应点击事件,但是ViewPager无法切换到相应的tab0X布局后来在修改了一下Compile Sdk Version和Build Tools Version之后(本来是6.0和23.0.2,然后换成低版本的,出现了Cannot resolve symbol ‘R’的问题,就又换了回去,之后上述的问题就变正常了)
源码:http://download.csdn.net/download/qq_22804827/9457018
相关文章推荐
- Android--Activity
- 四则运算(带括号)的小程序
- Android--入门
- 基于Android Webview的Hybrid App开发的前端优化
- [绍棠] xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)
- mac os使用lsusb命令和连接未知的Android设备
- 隐藏式抽屉(SlidingDrawer)
- unity屏幕shader之水屏幕
- Unity3d 游戏汉化之IL注入文本替换--木石世纪
- /Users/alamps/AndroidStudioProjects/Demo10ScrollView
- You Only Look Once: Unified, Real-Time Object Detection
- APP应用接入ApplePay
- Android Parcelable和Serializable的区别
- Android Studio添加aar包依赖
- android ndk安装
- Cocos2d-x之文件操作
- 安卓自定义View组件
- 关于iOS开发中长按保存图片到相册
- iOS中assign、copy 、retain关键字的真正含义
- 离开与关闭程序的弹出窗口(对话框上的Icon图标)