实现的效果图:
要实现这种联动的效果图,就需要使用CoordinatorLayout,这是一个专门为联动而生的控件。在这种效果图中,我们先来学习下TabLayout的使用。
public class TabLayout extends HorizontalScrollView
可以看到是继承HorizontalScrollView而开发的一个控件。它就是用来实现我们的顶部Tab页。
TabLayout的使用,需要添加Tab页进行。这里的Tab类是TabLayout的一个静态内部类,并且其构造方法是包内可访问的,也就是说你无法在外部构造其实例,只能通过TabLayout的newTab方法。
tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tabFirst = tabLayout.newTab();
tabFirst.setText("TabFirst");
tabLayout.addTab(tabFirst);
TabLayout.Tab tabSecond = tabLayout.newTab();
tabSecond.setText("tabSecond");
tabLayout.addTab(tabSecond);
TabLayout.Tab tabThird = tabLayout.newTab();
tabThird.setText("tabThird");
tabLayout.addTab(tabThird);
一个是在我手机真机上的效果,一个是在模拟器上的效果,同样版本的api17,不知道为什么效果差别如此之大。
如果能将TabLayout与ViewPager绑定那效果美的让人难以想象,在也不用那么复杂处理Indicator了。TabLayout中已经给我们提供setupWithViewPager方法让我们来绑定了。
(1)、先来看布局文件:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#FF0000"
app:tabSelectedTextColor="#00FF00"
app:tabTextColor="#FFFFFF"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
<android.support.design.widget.FloatingActionButton android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
app:borderWidth="0dp"/>
</android.support.design.widget.CoordinatorLayout>
(2)、在MainActivity中进行处理。
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(new ListViewLayout(getApplication()), position);
return container.getChildAt(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeViewAt(position);
}
});
initTabLayout();
}
private void initTabLayout(){
tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tabFirst = tabLayout.newTab();
tabFirst.setText("TabFirst");
tabLayout.addTab(tabFirst);
TabLayout.Tab tabSecond = tabLayout.newTab();
tabSecond.setText("tabSecond");
tabLayout.addTab(tabSecond);
TabLayout.Tab tabThird = tabLayout.newTab();
tabThird.setText("tabThird");
tabLayout.addTab(tabThird);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
在上例中我们使用了一个还有ListView的视图View来填充ViewPager。
看下效果图。
我们确实实现了效果,但是却没有了Tab页的标题。这是为什么呢?我们需要看下setupWithViewPager(ViewPager viewPager)的源码。
public void setupWithViewPager(ViewPager viewPager) {
PagerAdapter adapter = viewPager.getAdapter();
if(adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
} else {
this.setTabsFromPagerAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
}
}
在该方法中首先判断viewPager的adapter是否为null,如果为null抛出异常。所以我们在使用这个方法前,应该给viewpager设置好adapter才行。接着我们看this.setTabsFromPagerAdapter(adapter)这个方法。
public void setTabsFromPagerAdapter(PagerAdapter adapter) {
this.removeAllTabs();
int i = 0;
for(int count = adapter.getCount(); i < count; ++i) {
this.addTab(this.newTab().setText(adapter.getPageTitle(i)));
}
}
在这个方法中,使用removeAllTabs()方法删除所有的Tab页,然后遍历adapter进行生成tab页,这里调用adapter的getPageTitle方法设置tab页的名称。所以我们的adapter需要重写getPageTitle方法。
由于我们没有重写该方法,所以导致title无法显示,同样,我们也不需要手动添加tab页,只需要在getPageTitle方法中进行判断即可。
修改后的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(new ListViewLayout(getApplication()), position);
return container.getChildAt(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeViewAt(position);
}
@Override
public CharSequence getPageTitle(int position) {
if (position % 3 == 0) {
return "新闻世界";
} else if (position % 3 == 1) {
return "IT新闻";
} else {
return "Mr_dsw博客";
}
}
});
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
效果图就是这样子。
仔细的同学,可以看到我们设置了以下属性:
(1)、app:layout_scrollFlags:它有四个值,分别是:
(2)、app:layout_behavior:为了ToolBar可以滚动,CoordinatorLayout里面,放一个带有可滚动的View.CoordinatorLayout包含的子视图中带有滚动属性的View需要设置app:layout_behavior属性。
但是我们设置了该属性但是依旧无法实现需要的伸缩,后来无果,我将ListView改为RecyclerView,竟然可以滚动了,这点我也不晓得怎么个情况。
看下RecycerView的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" />
</LinearLayout>
我们自定义一个View。
/** * Created by dsw on 2015/11/8. */
public class RecyclerViewLayout extends LinearLayout {
public RecyclerViewLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public RecyclerViewLayout(Context context) {
super(context);
initView(context);
}
private void initView(Context context){
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view,this);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(new MyAdapter(context));
}
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
String[] data = new String[]{"A","B","C","D","E",
"F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Z","Y","Z"};
Context context;
public MyAdapter(Context context){
this.context = context;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
TextView textView = new TextView(context);
textView.setTextColor(Color.parseColor("#000000"));
textView.setTextSize(17*getResources().getDisplayMetrics().scaledDensity);
textView.setPadding(20,20,20,20);
return new MyViewHolder(textView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_textView.setText(data[position]);
}
@Override
public int getItemCount() {
return data.length;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView tv_textView;
public MyViewHolder(View itemView) {
super(itemView);
tv_textView = (TextView) itemView;
}
}
}
}
我们只需要在PagerAdapter中修改。
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(new RecyclerViewLayout(getApplication()), position);
return container.getChildAt(position);
}
这样就可以了。效果图:
源码下载地址:下篇后一起上传吧!
作者:mr_dsw 欢迎转载,与人分享是进步的源泉!
转载请保留地址:http://blog.csdn.net/mr_dsw