Tabhost 和 android.support.v4.view.ViewPager 整合的问题

sciolist 2012-02-24 11:17:39
最近在做一个将tabhost 改成 tabcontent 部位可左右滑动的东西。使用了谷歌提供的android.support.v4 包里面的viewpager组件.

原理就是把tabhost 里原有的的tabcontent 隐藏掉,加一个viewpager,捕捉事件进而进行互相刷新的动作。

唯一有所不同的就是tabhost里的content是各个单独的Activity.

具体代码如下:


主窗口


package org.xzx;

import android.app.Activity;
import android.app.LocalActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;

import java.util.ArrayList;

public class TestViewpageActivity extends Activity {

Context context = null;

LocalActivityManager manager = null;

ViewPager pager = null;

TabHost tabHost = null;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

context = TestViewpageActivity.this;
manager = new LocalActivityManager(this, true);
manager.dispatchCreate(savedInstanceState);

tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabHost.setup(manager);
tabHost.addTab(tabHost.newTabSpec("A").setIndicator("A")
.setContent(new Intent(context, A.class)));
tabHost.addTab(tabHost.newTabSpec("B").setIndicator("B")
.setContent(new Intent(context, B.class)));
tabHost.addTab(tabHost.newTabSpec("C").setIndicator("C")
.setContent(new Intent(context, C.class)));
tabHost.addTab(tabHost.newTabSpec("D").setIndicator("D")
.setContent(new Intent(context, D.class)));

tabHost.setOnTabChangedListener(new OnTabChangeListener() {

@Override
public void onTabChanged(String tabId) {
if ("A".equals(tabId)) {
pager.setCurrentItem(0);
} else if ("B".equals(tabId)) {
pager.setCurrentItem(1);
} else if ("C".equals(tabId)) {
pager.setCurrentItem(2);
} else {
pager.setCurrentItem(3);
}
}
});

pager = (ViewPager) findViewById(R.id.viewpage);
final ArrayList<View> list = new ArrayList<View>();
Intent intent = new Intent(context, A.class);
list.add(getView("A", intent));
Intent intent2 = new Intent(context, B.class);
list.add(getView("B", intent2));
Intent intent3 = new Intent(context, C.class);
list.add(getView("C", intent3));
Intent intent4 = new Intent(context, D.class);
list.add(getView("D", intent4));

pager.setAdapter(new PagerAdapter() {

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
ViewPager pViewPager = ((ViewPager) arg0);
pViewPager.removeView(list.get(arg1));
}

@Override
public void finishUpdate(View arg0) {
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object instantiateItem(View arg0, int arg1) {
ViewPager pViewPager = ((ViewPager) arg0);
pViewPager.addView(list.get(arg1));
return list.get(arg1);
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}

@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}

@Override
public Parcelable saveState() {
return null;
}

@Override
public void startUpdate(View arg0) {
}
});

pager.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int arg0) {
tabHost.setCurrentTab(arg0);
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}

@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}

private View getView(String id, Intent intent) {
return manager.startActivity(id, intent).getDecorView();
}
}



对应的布局:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>

<android.support.v4.view.ViewPager
android:id="@+id/viewpage"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" >
</FrameLayout>
</LinearLayout>

</TabHost>


子窗口A:

/**
*
*/

package org.xzx;

import android.app.Activity;
import android.os.Bundle;

/**
* @author sharl
* @date 2012-2-23 上午10:51:57
* @usage
*/
public class A extends Activity {

/**
*
*/
public A() {
}

/*
* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a);
}

}



对应的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="AAAAAAAAAAAA" />

</LinearLayout>


还有类似于A.class 的B.class、C.class、D.class. 不列举.

问题来了,当我左右滑动viewpager的时候,A 和 B 不能同时显示出来,只有等滑过来了之后,才会显示下一个标签里的内容。

求高手解释,谢谢.
...全文
6480 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
晨曦1112 2014-02-20
  • 打赏
  • 举报
回复
不错的东西,测试了下,没问题,谢谢!!!
钢琴冰指 2013-04-10
  • 打赏
  • 举报
回复
这样效果不错
「已注销」 2012-12-31
  • 打赏
  • 举报
回复
引用 8 楼 mmvc2010 的回复:
首先谢谢楼主的分享,经过自己验证,发现代码中有一个问题,当添加Tab页的时候,把内容设成旁边的页面,这样会导致getCurrentActivity并不是当前看到的页面,比如我的A.class中包含了一个webview,当我从webview的页面点击进入后,按返回建我想回到webview之前显示的那个界面,那么我在A.class中重写onKeyDown方法,并判断webvi……
TabHost, ViewPager这俩东东本来都是用来分页展示内容的, 这么拿来拼凑是不是有点太浪费资源了.... RadioGroup+ViewPager相对来说, 应该更合理点.
zclove898 2012-11-13
  • 打赏
  • 举报
回复
感谢楼主分享,正我我想要的
W710327M 2012-09-05
  • 打赏
  • 举报
回复
lz太强大了、。。学习了。。
xwlljjxwlljj 2012-08-21
  • 打赏
  • 举报
回复
很不错的东东
影像Diordna 2012-05-31
  • 打赏
  • 举报
回复
楼上2_____b
钱大进 2012-05-31
  • 打赏
  • 举报
回复
..晕,写到最后面的,看到了,不好意思。
钱大进 2012-05-31
  • 打赏
  • 举报
回复
那个intent后 getView("a",intent1);这个方法我的怎么没有?
zxiaoqiangg 2012-05-25
  • 打赏
  • 举报
回复
谢谢 学习了
sciolist 2012-05-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

首先谢谢楼主的分享,经过自己验证,发现代码中有一个问题,当添加Tab页的时候,把内容设成旁边的页面,这样会导致getCurrentActivity并不是当前看到的页面,比如我的A.class中包含了一个webview,当我从webview的页面点击进入后,按返回建我想回到webview之前显示的那个界面,那么我在A.class中重写onKeyDown方法,并判断webview是否可以返回,然后在……
[/Quote]

谢谢分享!
xubo115 2012-05-22
  • 打赏
  • 举报
回复
确实用tabhost加viewpager太不方便了

mmvc2010 2012-04-20
  • 打赏
  • 举报
回复
首先谢谢楼主的分享,经过自己验证,发现代码中有一个问题,当添加Tab页的时候,把内容设成旁边的页面,这样会导致getCurrentActivity并不是当前看到的页面,比如我的A.class中包含了一个webview,当我从webview的页面点击进入后,按返回建我想回到webview之前显示的那个界面,那么我在A.class中重写onKeyDown方法,并判断webview是否可以返回,然后在TestViewpageActivity中也重写onKeyDown方法,getCurrentActivity.onKeyDown,这样并不会调用我在A.class中写的方法,因为getCurrentActivity并不是A的实例
解决办法:直接使用ActivityGroup+ViewPager实现,效果是一样,Tab可以用RadioGroup实现,而且这样更容易自定义菜单栏的样式等。
mmvc2010 2012-04-20
  • 打赏
  • 举报
回复
首先谢谢楼主的分享,经过自己验证,发现代码中有一个问题,当添加Tab页的时候,把内容设成旁边的页面,这样会导致getCurrentActivity并不是当前看到的页面,比如我的A.class中包含了一个webview,当我从webview的页面点击进入后,按返回建我想回到webview之前显示的那个界面,那么我在A.class中重写onKeyDown方法,并判断webview是否可以返回,然后在TestViewpageActivity中也重写onKeyDown方法,getCurrentActivity.onKeyDown,这样并不会调用我在A.class中写的方法,因为getCurrentActivity并不是A的实例
解决办法:直接使用ActivityGroup+ViewPager实现,效果是一样,Tab可以用RadioGroup实现,而且这样更容易自定义菜单栏的样式等。
:-)
sciolist 2012-03-07
  • 打赏
  • 举报
回复
上面样式乱了,重发下。

[Quote]
tabHost.addTab(tabHost.newTabSpec("A").setIndicator("A")
.setContent(new Intent(context, B.class)));
tabHost.addTab(tabHost.newTabSpec("B").setIndicator("B")
.setContent(new Intent(context, C.class)));
tabHost.addTab(tabHost.newTabSpec("C").setIndicator("C")
.setContent(new Intent(context, D.class)));
tabHost.addTab(tabHost.newTabSpec("D").setIndicator("D")
.setContent(new Intent(context, A.class)));
[/Quote]
sciolist 2012-03-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 huazai070 的回复:]

主Activity继承TabActivity,
然后

tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabHost.setup(manager);

改成 tabHost = getTabHost();
就可以实现内容的和动画同步了

另外你……
[/Quote]

谢谢。我已经找到解决方案了。

一个小把戏而已,就是当你添加Tab页的时候,把内容设成旁边的页面就可以了。


tabHost.addTab(tabHost.newTabSpec("A").setIndicator("A")
.setContent(new Intent(context, B.class)));
tabHost.addTab(tabHost.newTabSpec("B").setIndicator("B")
.setContent(new Intent(context, C.class)));
tabHost.addTab(tabHost.newTabSpec("C").setIndicator("C")
.setContent(new Intent(context, D.class)));
tabHost.addTab(tabHost.newTabSpec("D").setIndicator("D")
.setContent(new Intent(context, A.class)));

即可。

至于你说的那个跨标签出错问题,我没有遇到。
sciolist 2012-03-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 feitianwujinxishan 的回复:]

使用官方的代码时,提示找不到FragmentStackSupport、LoaderCursorSupport、LoaderCustomSupport、LoaderThrottleSupport四个类,我去android-support-v4.jar中找不到相应的类,应该怎么处理呀?
[/Quote]
把你的support lib 包更新一下。
huazai070 2012-03-05
  • 打赏
  • 举报
回复
主Activity继承TabActivity,
然后

tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabHost.setup(manager);

改成 tabHost = getTabHost();
就可以实现内容的和动画同步了

另外你的OnTabChangeListener()有问题,跨一个tab点击就会出错,
是if判断的问题,不用else
zhonglushu 2012-03-01
  • 打赏
  • 举报
回复
官方有个例子呀,可以去研究一下!
zhonglushu 2012-03-01
  • 打赏
  • 举报
回复
使用官方的代码时,提示找不到FragmentStackSupport、LoaderCursorSupport、LoaderCustomSupport、LoaderThrottleSupport四个类,我去android-support-v4.jar中找不到相应的类,应该怎么处理呀?
加载更多回复(1)

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧