您的位置:首页 > 移动开发

多种多样的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布局文件讲解一下,其中
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: