android实现可滑动标签页有很多方法,这里给大家介绍一种官方推荐,性能最高,并且代码最少的方式,就是利用FragmentTabhost+ViewPager+FragmentPagerAdapter来实现。
先看下效果图:
主要代码如下:
MainActivity.class
package zwp.fragmenttabhost;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import zwp.adapter.TabsFragmentPagerAdapter;
import zwp.fragment.MyFragment;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.widget.TextView;
import android.widget.TabHost.OnTabChangeListener;
/**
* 为了支持2.x版本要继承FragmentActivity,使用getSupportFragmentManager()
* @author 周文鹏
* @date 2015-8-28
*/
public class MainActivity extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener {
// tabhost
private static final String[] IDS = {"frag_1", "frag_2", "frag_3", "frag_4"};
private static final String[] TITLES = {"第一页", "第二页", "第三页", "第四页"};
private List<String> ids = Arrays.asList(IDS);
private FragmentTabHost tabHost;
// viewpager
private static final int[] COLORS = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
private ViewPager viewPager;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_main);
// 这个是传入viewpageradpter中的4个MyFragment数组
List<Fragment> fragments = new ArrayList<Fragment>(IDS.length);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
for (int i = 0; i < IDS.length; i++) {
/*
* 这里建议传一个空的fragment,即Fragment.class,
* 因为要用到viewpager来显示fragment,而真正的android.R.id.tabcontent在xml布局中layout_height设置为0dp隐藏起来,
* 如果设置成MyFragment.class,那么在MyFragment中定义的一些代码也会被执行,浪费资源。
*/
tabHost.addTab(tabHost.newTabSpec(IDS[i]).setIndicator(
createTabView(TITLES[i])),
Fragment.class, null);
/*
* 可以使用Fragment.instantiate方式获取MyFragment实例并传递参数,
* 如果不需要传递参数则直接new MyFragment()也可以
*/
Bundle bundle = new Bundle();
bundle.putString("title", TITLES[i]);
bundle.putInt("color", COLORS[i]);
fragments.add(Fragment.instantiate(this, MyFragment.class.getName(), bundle));
}
// 设置tanhost切换监听
tabHost.setOnTabChangedListener(this);
// viewpager
viewPager = (ViewPager) findViewById(R.id.main_viewpager);
viewPager.setAdapter(new TabsFragmentPagerAdapter(getSupportFragmentManager(), fragments));
viewPager.setOnPageChangeListener(this);
}
/**
* OnTabChangeListener
* 监听tabhost切换,并设置viewpager切换
*/
@Override
public void onTabChanged(String tabId) {
int position = ids.indexOf(tabId);
viewPager.setCurrentItem(position);
}
/**
* OnPageChangeListener
* 监听viewpager滑动切换,并设置tabhost切换
*/
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
tabHost.setCurrentTab(arg0);
}
/**
* 创建tab View
* @param string
* @return
*/
private View createTabView(String text) {
View tabView = getLayoutInflater().inflate(R.layout.tab, null);
TextView textView = (TextView) tabView.findViewById(R.id.tab_text);
textView.setText(text);
return tabView;
}
}
MyFragment.java
package zwp.fragment;
import zwp.fragmenttabhost.R;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_my, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View view = getView();
TextView textView = (TextView) view.findViewById(R.id.fragment_my_text);
// 获取Activity传来的参数
Bundle bundle = getArguments();
// 设置背景色
view.setBackgroundColor(bundle.getInt("color"));
// 设置文字
textView.setText(bundle.getString("title"));
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 这个@android:id/tabs虽然在代码中没有用findViewById获取,但是一定要写,FragmentTabHost中会去调用,
另外,如果发现这个显示不正常(只有背景色,没有文字),应该是你android-support-v4.jar包太老了,
google每次更新sdk都会修改android-support-v4.jar包,下个最新的就可以了,更换jar包后还是有问题就clean一下。 -->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/tab_widget_bg"/>
<android.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
这里说明下需要注意几个问题,这些问题我在代码中也注释了:
1.在MainActivity.java中构造FragmentTabHost.TabSpec时传一个空的fragment,即Fragment.class,因为要用到viewpager来显示fragment,而真正的android.R.id.tabcontent在xml布局中layout_height设置为0dp隐藏起来,如果设置成MyFragment.class,那么在MyFragment中定义的一些代码也会被执行,浪费资源。不知道有没有大神有更好的办法,就是让TabHost和ViewPager共用一个Fragment,我暂时还没有找到。
2.在activity_main.xml中@android:id/tabs虽然在代码中没有用findViewById获取,但是一定要写,FragmentTabHost中会去调用,另外,如果发现这个显示不正常(只有背景色,没有文字),应该是你android-support-v4.jar包太老了,google每次更新sdk都会修改android-support-v4.jar包,下个最新的就可以了,更换jar包后还是有问题就clean一下。
以上效果是在android4.0手机上运行的效果,最低兼容android2.2(其实最低可以兼容android1.6,也就是api4)。
Demo下载地址: http://download.csdn.net/detail/syaringan356/9058053