我决定创建一个小型库,使用ViewPager,Tabhost和FragmentActivity创建出色的菜单。所以我有3个小班:
绘制菜单(绘制所有xml内容)
public class DrawAMKMenu extends FragmentActivity {
protected LinearLayout mLinearLayout;
protected static TabHost mTabHost;
protected static Context mContext;
protected ViewPager mViewPager;
protected RelativeLayout mMenuBar;
protected Resources res;
protected int screenwidth;
protected Drawable ThumbResource = null;
protected Drawable menuBg = null;
protected TabWidget tw;
/**
* constructor
* @param c
* @param main_layout
*/
protected DrawAMKMenu(FragmentActivity fa, LinearLayout main_layout){
mContext = fa.getApplicationContext();
mLinearLayout = main_layout;
res = fa.getResources();
Display display = fa.getWindowManager().getDefaultDisplay();
screenwidth = display.getWidth();
}
/**
*Draw main LinearLayout
*/
protected void DrawMenu()
{
mLinearLayout.removeAllViews();
mLinearLayout.setBaselineAligned(true);
mLinearLayout.setOrientation(LinearLayout.VERTICAL);
mLinearLayout.addView(createTabHost());
}
/**
* @return TabHost
* draw the TabHost view
*/
protected TabHost createTabHost(){
mTabHost = new TabHost(mContext);
mTabHost.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
mTabHost.addView(createTabContentLayout());
mTabHost.addView(createViewPager());
mTabHost.addView(createMenuBar());
mTabHost.setTag("TabHost");
SetupTabs(mTabHost);
return mTabHost;
}
/**
* Create FrameLayout for Content
* @return FrameLayout
*/
protected FrameLayout createTabContentLayout(){
/*Frame layout for Content*/
FrameLayout fl = new FrameLayout(mContext);
fl.setLayoutParams(new LinearLayout.LayoutParams(0,0,1));
fl.setId(android.R.id.tabcontent);
/*------------------------*/
return fl;
}
/**
* @return ViewPager
* draw ViewPager element
*/
protected ViewPager createViewPager(){
mViewPager = new ViewPager(mContext);
mViewPager.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,1));
mViewPager.setBackgroundColor(Color.WHITE);
mViewPager.setTag("viewpager");
return mViewPager;
}
/**
* @return RelativeLayout
* draw Menu bar
*/
protected RelativeLayout createMenuBar(){
/* Layout for Menu Bar */
mMenuBar = new RelativeLayout(mContext);
mMenuBar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
//mMenuBar.setGravity(Gravity.BOTTOM);
/* ------------------ */
/* Tab Widget*/
tw = new TabWidget(mContext);
tw.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT,0));
tw.setOrientation(LinearLayout.HORIZONTAL);
tw.setId(android.R.id.tabs);
if(menuBg != null)
tw.setBackgroundDrawable(menuBg);
/*-----------*/
/* Scroll bar for menu */
HorizontalScrollView hsv = new HorizontalScrollView(mContext);
hsv.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT,0));
hsv.setScrollBarStyle(View.GONE);
hsv.setFillViewport(true);
/* ----------------- */
//add tabWidget to HorizontalScrollView
hsv.addView(tw);
/*Seek Bar*/
SeekBar sb = new SeekBar(mContext);
sb.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
sb.setBackgroundColor(Color.TRANSPARENT);
sb.setProgressDrawable(res.getDrawable(android.R.id.empty));
if(ThumbResource!=null)
sb.setThumb(ThumbResource);
else
sb.setThumb(res.getDrawable(android.R.id.empty));
/*-------*/
/*Frame layout for SeekBar*/
FrameLayout fl = new FrameLayout(mContext);
fl.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
fl.addView(sb);
/*------------------------*/
mMenuBar.addView(hsv);
mMenuBar.addView(fl);
return mMenuBar;
}
/**
* Delete bottom strip from tabhost
* @param tabHost
*/
protected void SetupTabs(TabHost tabHost) {
Field mBottomLeftStrip;
Field mBottomRightStrip;
try {
mBottomLeftStrip = tw.getClass().getDeclaredField("mBottomLeftStrip");
mBottomRightStrip = tw.getClass().getDeclaredField("mBottomRightStrip");
if (!mBottomLeftStrip.isAccessible()) {
mBottomLeftStrip.setAccessible(true);
}
if (!mBottomRightStrip.isAccessible()) {
mBottomRightStrip.setAccessible(true);
}
mBottomLeftStrip.set(tw, res.getDrawable(Color.TRANSPARENT));
mBottomRightStrip.set(tw, res.getDrawable(Color.TRANSPARENT));
}
catch (java.lang.NoSuchFieldException e) {
// possibly 2.2
try {
Method stripEnabled = tw.getClass().getDeclaredMethod("setStripEnabled", boolean.class);
stripEnabled.invoke(tw, false);
}
catch (Exception e1) {
e1.printStackTrace();
}
}
catch (Exception e) {}
}
}
PagerAdapter类
public class PagerAdapter extends FragmentPagerAdapter
private List<Fragment> pFragments;
/**
* @param fm
* @param fragments
*/
public PagerAdapter(FragmentManager fm, List<Fragment> fr) {
super(fm);
this.pFragments = fr;
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
return this.pFragments.get(position);
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return this.pFragments.size();
}
}
创建菜单类。
公共类AMKMenu扩展DrawAMKMenu实现TabHost.OnTabChangeListener,ViewPager.OnPageChangeListener {
private PagerAdapter mPagerAdapter;
private Vector<Fragment> fragments;
private FragmentManager mFragmentManager;
private FragmentActivity mFragmentActivity;
private static HashMap<Integer, Class<?>> TabsClass;
private static HashMap<Integer, String> TabsTabName;
private static HashMap<Integer, Drawable> TabsIcon;
/**
* CONSTRUCTOR
* Create AMKMenu object to setup settings and
* also initialize menu
* @param c
* @param main_layout
* @param fm
* @param screenWidth
*/
public AMKMenu(FragmentActivity fa, LinearLayout main_layout) {
super(fa, main_layout);
mFragmentActivity = fa;
mFragmentManager = fa.getSupportFragmentManager();
TabsClass = new HashMap<Integer, Class<?>>();
TabsTabName = new HashMap<Integer, String>();
TabsIcon = new HashMap<Integer, Drawable>();
}
/**
* Final method to create menu
* Use it after you setup all settings
*/
public void createMenu(){
super.DrawMenu();
initializeTabHost();
intializeViewPager();
}
/**
* A simple factory that returns dummy views to the Tabhost
* @author Gavryschuk Anatoliy V.
*/
public class TabFactory implements TabContentFactory {
private final Context fContext;
/**
* @param context
*/
public TabFactory(Context context) {
fContext = context;
}
/** (non-Javadoc)
* @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(fContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
/**
* Initialize ViewPager
*/
protected void intializeViewPager() {
fragments = new Vector<Fragment>();
if(getTabsClass().size()>0)
{
for(int i=0;i<getTabsClass().size();i++)
{
fragments.add(Fragment.instantiate(mFragmentActivity, getTabsClass(i).getName()));
}
}
setPagerAdapter(new PagerAdapter (mFragmentManager, fragments));
mViewPager.setAdapter(getPagerAdapter());
mViewPager.setOnPageChangeListener(this);
}
/**
* Initialize the Tab Host
*/
protected void initializeTabHost() {
if(getTabsClass().size()>0)
{
TabHost mTabHost = (TabHost) mLinearLayout.findViewWithTag("TabHost");
mTabHost.setup();
for(int i=0;i<getTabsClass().size();i++)
{
TabSpec tabSpec = mTabHost.newTabSpec(getTabsTabName(i));
tabSpec.setIndicator(getTabsTabName(i), getTabsIcon(i));
tabSpec.setContent(new TabFactory(mFragmentActivity));
mTabHost.addTab(tabSpec);
}
mTabHost.setOnTabChangedListener(this);
mTabHost.getTabWidget().setHorizontalScrollBarEnabled(false);
for(int i=0;i<mTabHost.getTabWidget().getChildCount();i++)
{
//mTabHost.getTabWidget().getChildAt(i).setLayoutParams(new LinearLayout.LayoutParams(65,65));
mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(0);
}
// mTabHost.setCurrentTab(0);
}else
return;
}...
}
以这种方式使用这个库之后
AMKMenu menu = new AMKMenu(this, (LinearLayout)findViewById(R.id.main_layout));
menu.setMenuBg(getResources().getDrawable(R.drawable.menu_bg));
menu.setCursor(getResources().getDrawable(R.drawable.new_cursor));
menu.AddTab(Tab1Fragment.class, "tab1", getResources().getDrawable(R.drawable.f_icon));
menu.AddTab(Tab2Fragment.class, "tab2", getResources().getDrawable(R.drawable.s_icon));
menu.AddTab(Tab3Fragment.class, "tab3", getResources().getDrawable(R.drawable.t_icon));
menu.createMenu();
我收到错误
java.lang.IllegalArgumentException:找不到片段
的id的新内容
问题在于AMKMenu类中的intializeViewPager()方法。
请有人(Android大师)帮助我,我做错了什么? 我希望我能清楚地解释一切。
答案 0 :(得分:3)
听到我的解决方案(Tabs + Fragment + ViewPager)它对我来说很有用,希望对你有用
听到的是xml文件
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="5" />
<FrameLayout
android:id="@+id/fragment_details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="4.3" />
</LinearLayout>
听到是MainActivity.java的代码我只发布相关代码,所以你必须管理它
public class MainActivity extends FragmentActivity implements
DialogInterface.OnDismissListener, TabDataResponder {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
artistTab = getSupportActionBar().newTab().setText(
R.string.tab_name_artist);
albumTab = getSupportActionBar().newTab().setText(
R.string.tab_name_album);
songTab = getSupportActionBar().newTab().setText(
R.string.tab_name_songs);
map = new HashMap<String, Integer>();
mViewPager = (ViewPager) findViewById(R.id.pager);
FrameLayout deatil = (FrameLayout) findViewById(R.id.fragment_details);
mDualPane = (deatil != null) && (deatil.getVisibility() == View.VISIBLE);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
if (savedInstanceState != null) {
flag = true;
index = savedInstanceState.getInt("index");
}
setUpTabView();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar()
.getSelectedNavigationIndex());
}
private void setUpTabView() {
mTabsAdapter.addTab(artistTab, ArtistFragment.class, null);
mTabsAdapter.addTab(albumTab, AlbumFragment.class, null);
mTabsAdapter.addTab(songTab, SongFragment.class, null);
getSupportActionBar().setSelectedNavigationItem(index);
}
public static class TabsAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, ActionBar.TabListener {
private FragmentActivity mContext;
private ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
private TabDataResponder responder;
public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
// TabDataResponder is an interface which is implemented in MainActivity
// You can find implementation @ the last
responder = (TabDataResponder) activity;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
//I have used map to save state of the fragment
map.put(SongFragment.TYPE_FRAGMENT.trim(), 0);
map.put(AlbumFragment.TYPE_FRAGMENT.trim(), 0);
map.put(ArtistFragment.TYPE_FRAGMENT.trim(), 0);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
mTabs.add(clss.getName());
// mArgs.add(args);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return Fragment
.instantiate(mContext, mTabs.get(position), /*
* mArgs.get(
* position)
*/null);
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Log.i(TAG, "PageSelected....");
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.i(TAG, "ScrollSateChanged....");
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
String a = null;
if (mDualPane) {
a = mTabs.get(tab.getPosition());
responder.loadData(a, map.get(a));
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "Tab is released now....");
}
}
@Override
public void onDismiss(DialogInterface dialog) {
setUpTabView();
}
//This interface must be call from fragment class
//@ the time of event you want to show detail
// pass the class name in the type argument using class.getName() method
@Override
public void loadData(String type, int index) {
DetailFragment viewer = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_details);
if (mDualPane) {
if (viewer == null || viewer.getShownIndex() != index
|| viewer.getTypeFragment() != type) {
DetailFragment df = DetailFragment.newInstance(index, type);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_details, df)
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
map.put(type.trim(), index);
}
} else {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DetailActivity.class);
intent.putExtra("index", index);
intent.putExtra("type", type);
startActivity(intent);
}
}
}
并且听说我是如何处理细节片段效率不高但工作有点
public class DetailFragment extends Fragment{
public static DetailFragment newInstance(int index, String TYPE_FRAGMENT) {
DetailFragment f = new DetailFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
args.putString("type", TYPE_FRAGMENT);
f.setArguments(args);
return f;
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
public String getTypeFragment(){
String a = getArguments().getString("type");
return a;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//template is blank layout
View view = inflater.inflate(R.layout.template, container, false);
if(getTypeFragment().equals(ArtistFragment.TYPE_FRAGMENT)){
view = null;
view = inflater.inflate(R.layout.artist_details, container, false);
//....
}
else if(getTypeFragment().equals(AlbumFragment.TYPE_FRAGMENT)){
//do's for album fragment
}
else if(getTypeFragment().equals(SongFragment.TYPE_FRAGMENT)){
//do's for song fragment
}
return view;
}
}
不要将标签状态保存在各自的片段中会发生冲突,我们已经在听取了
希望它有助于