在使用TabActivity和片段以及viewPager等标签实现常用方法的一周之后,我无法获得活动或标签片段的实例,但无法找到解决问题的方法。所以我决定以不同的方式实现它。首先,我用一个简单的按钮制作一个tabWidget。在android开发者网站中,我找到了一种在运行时替换片段的方法。所以唯一剩下的就是如何访问制表符片段来调用FragmentActivity中的方法。
这是我使用pageViewer的FragmentActivity。当我想在setup()
方法中获取我的选项卡的片段对象时,我得到nullpointer:
public class MainActivity extends FragmentActivity implements
OnTabChangeListener, OnPageChangeListener {
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, MainActivity.TabInfo>();
private PagerAdapter mPagerAdapter;
private TabInfo mLastTab = null;
private class TabInfo {
private String tag;
private Class clss;
private Bundle args;
private Fragment fragment;
TabInfo(String tag, Class clazz, Bundle args) {
this.tag = tag;
this.clss = clazz;
this.args = args;
}
}
class TabFactory implements TabContentFactory {
private final Context mContext;
/**
* @param context
*/
public TabFactory(Context context) {
mContext = context;
}
/**
* (non-Javadoc)
*
* @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Log.d("checking", "setup tabs...");
setContentView(R.layout.activity_main);
// //
initialiseTabHost(savedInstanceState);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
intialiseViewPager();
// //
setup();
// ///
}
protected void onSaveInstanceState(Bundle outState) {
outState.putString("tab", mTabHost.getCurrentTabTag()); // save the tab
// selected
super.onSaveInstanceState(outState);
}
private void intialiseViewPager() {
List<Fragment> fragments = new Vector<Fragment>();
fragments
.add(Fragment.instantiate(this, CoachFragment.class.getName()));
fragments
.add(Fragment.instantiate(this, LogingFragment.class.getName()));
fragments.add(Fragment.instantiate(this,
HistoryFragment.class.getName()));
this.mPagerAdapter = new PagerAdapter(
super.getSupportFragmentManager(), fragments);
//
this.mViewPager = (ViewPager) super.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
mViewPager.setOffscreenPageLimit(1000000);
}
private void initialiseTabHost(Bundle args) {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabHost.getTabWidget().setDividerDrawable(R.drawable.tab_divider);
TabInfo tabInfo = null;
View tabView1 = createTabView(this, coach");
MainActivity.AddTab(this, this.mTabHost, this.mTabHost
.newTabSpec("Tab1").setIndicator(tabView1),
(tabInfo = new TabInfo("Tab1", CoachFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
View tabView2 = createTabView(this, logbook");
MainActivity.AddTab(this, this.mTabHost, this.mTabHost
.newTabSpec("Tab2").setIndicator(tabView2),
(tabInfo = new TabInfo("Tab2", LogingFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
View tabView3 = createTabView(this, "history");
MainActivity.AddTab(this, this.mTabHost, this.mTabHost
.newTabSpec("Tab3").setIndicator(tabView3),
(tabInfo = new TabInfo("Tab3", HistoryFragment.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
mTabHost.setOnTabChangedListener(this);
}
private static void AddTab(MainActivity activity, TabHost tabHost,
TabHost.TabSpec tabSpec, TabInfo tabInfo) {
// Attach a Tab view factory to the spec
tabSpec.setContent(activity.new TabFactory(activity));
tabHost.addTab(tabSpec);
}
public void setup() {
....
CoachFragment fragment=(CoachFragment) mPagerAdapter.getRegisteredFragment(mViewPager.getCurrentItem());
fragment.setTempView(R.id.welcome);
fragment.animate();
....
}
public void onTabChanged(String tag) {
// TabInfo newTab = this.mapTabInfo.get(tag);
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
private static View createTabView(final Context context, final String text) {
View view = LayoutInflater.from(context)
.inflate(R.layout.tabs_bg, null);
TextView tv = (TextView) view.findViewById(R.id.tabsText);
tv.setText(text);
return view;
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
this.mTabHost.setCurrentTab(position);
}
}
my pageAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private HashMap<Integer, Fragment> registeredFragments=new HashMap<Integer, Fragment>();
/**
* @param fm
* @param fragments
*/
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return this.fragments.size();
}
}
和我的LogingFragment。其他2个片段完全相同:
public class LogingFragment extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
// We have different layouts, and in one of them this
// fragment's containing frame doesn't exist. The fragment
// may still be created from its saved state, but there is
// no reason to try to create its view hierarchy because it
// won't be displayed. Note this is not needed -- we could
// just run the code below, where we would create and return
// the view hierarchy; it would just never be used.
return null;
}
return (LinearLayout)inflater.inflate(R.layout.coach_activity, container, false);
}
}
每件事都很完美,所有看起来和滑动都很好但是在setup()方法中我得到了nullPointer。请帮帮我。
答案 0 :(得分:1)
我强烈建议运行并测试使用Tabs和ViewPager的样本有效导航
http://developer.android.com/training/implementing-navigation/index.html
答案 1 :(得分:1)
最后我想出了nullpointer的原因是什么。寻呼机适配器应该是这样的:
public class PagerAdapter extends FragmentPagerAdapter {
Fragment screens[];
public PagerAdapter(FragmentManager fm, MainActivity context) {
super(fm);
screens = new Fragment[3];
screens[0] = Fragment.instantiate(context,CoachFragment.class.getName() );
screens[1] = Fragment.instantiate(context,LogingFragment.class.getName() );
screens[2] = Fragment.instantiate(context,HistoryFragment.class.getName() );
}
@Override
public Fragment getItem(int index) {
if(index <= screens.length)
{
return screens[index];
}
return null;
}
@Override
public int getCount() {
return screens.length;
}
}
如此实例化视图寻呼机的变化如下:
private void intialiseViewPager() {
this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(),this);
//
this.mViewPager = (ViewPager) super.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
//
this.mViewPager = (ViewPager) super.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
}
感谢@Bruno Mateus
答案 2 :(得分:0)
在我看来,你似乎是Android的新手,所以让我指出你正确的方向(如果你不是Android的新手,我的道歉):
如果您想在应用中使用标签,最新且最好的方法是使用Action Bar tabs。
这只涉及修改menu.xml
文件并在主要活动中添加onCreateOptionsMenu()
方法。
另外,要回答你的问题,
所以唯一剩下的就是如何访问制表符片段以从我的FragmentActivity中调用方法
您不应该使用片段来调用片段活动中的方法。
同样,我将通过此视频 "Programming Android with fragments"向您指出正确的方向。它有点长,但它将解释如何使用碎片。
使用视频的片段示例,并将其与操作栏标签页中的示例代码相结合。
祝你好运
**快速编辑以澄清:您应该使用操作栏标签,因为这是使用标签的最新和最简单的方法。这是新的“最佳实践”。 TabWidget和TabActivity更老,更复杂,甚至可能已被弃用。
答案 3 :(得分:0)
试试GrilledUI库。它将为您完成所有脏工作,甚至可以从XML加载选项卡列表。