效果图:
代码实现:ViewPager+Fragment实现了Tabhost,动态添加删除Fragment,暴露三个可重写的多态方法供第三方调用:
protected Fragment getFragmentAt(int pos) { return null; } protected View getIndicatorAt(int pos) { return null; } protected int getItemsCount() { return 0; }
项目第三方类库测试用的主MainActivity.java
import java.util.ArrayList; import java.util.Random; 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.FragmentTransaction; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment newFragment = new HowToUseThisView(); FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); transaction.replace(R.id.fragment, newFragment); transaction.commit(); } public static class HowToUseThisView extends ViewPagerAndFragmentTabHost { private ArrayList<Fragment> mArrayList; private int id = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mArrayList = new ArrayList<Fragment>(); } @Override protected Fragment getFragmentAt(int pos) { Fragment fragment = null; try { fragment = mArrayList.get(pos); } catch (Exception e) { Log.d(this.getClass().getName(), "队列中不存在,创建新Fragment"); } if (fragment == null) { fragment = new TestFragment(); ((TestFragment) fragment).setID(id++); mArrayList.add(fragment); } return fragment; } @Override protected View getIndicatorAt(int pos) { // 简单期间,先就用TextView作为底部Tab的选项卡 TextView tv = new TextView(getActivity()); tv.setGravity(Gravity.CENTER); tv.setText("Tab " + pos); return tv; } @Override protected int getItemsCount() { // 假设随机生成此数目的一组Fragment和Tab选项卡 Random rand = new Random(); return rand.nextInt(5); } @Override public void onStart() { super.onStart(); super.notifyDataSetChanged(); } } // // 仅仅用于测试的Fragment,在ViewPager中加载 // public static class TestFragment extends Fragment { private int id; public void setID(int id) { this.id = id; } public int getID() { return id; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView tv = new TextView(getActivity()); String str = "序号: " + getID(); tv.setTextColor(Color.LTGRAY); tv.setText(str); tv.setTextSize(50); tv.setGravity(Gravity.CENTER); return tv; } } }
MainActivity.java需要的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" > <FrameLayout android:id="@+id/fragment" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout>
可供第三方调用的ViewPagerAndFragmentTabHost.java类,重点。
import java.util.ArrayList; import java.util.HashMap; import java.util.UUID; import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; public class ViewPagerAndFragmentTabHost extends Fragment { private MyFragmentPagerAdapter mPagerAdapter; private ViewPager mViewPager; private LinearLayout mLinearLayout; private ArrayList<HashMap<String, Object>> mArrayList = null; private final String FRAGMENT = "fragment_tag", TAB = "tab_tag", UUID_TAG = "uuid_tag"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mArrayList = new ArrayList<HashMap<String, Object>>(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View mView = inflater.inflate(R.layout.viewpager_fragment, null); mViewPager = (ViewPager) mView.findViewById(R.id.viewpager); mLinearLayout = (LinearLayout) mView .findViewById(R.id.indicator_LinearLayout); mPagerAdapter = new MyFragmentPagerAdapter(getFragmentManager()); mViewPager.setAdapter(mPagerAdapter); mViewPager .setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int pos) { set(pos); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); return mView; } @Override public void onStart() { super.onStart(); // 初始化选择第一项 if (mPagerAdapter.getCount() > 0) { set(0); } for (int i = 0; i < getItemsCount(); i++) { add(getFragmentAt(i), getIndicatorAt(i)); } } public void notifyDataSetChanged() { mPagerAdapter.notifyDataSetChanged(); } protected Fragment getFragmentAt(int pos) { return null; } protected View getIndicatorAt(int pos) { return null; } protected int getItemsCount() { return 0; } private void add(Fragment fragment, View indicatorView) { HashMap<String, Object> map = new HashMap<String, Object>(); UUID uuid = UUID.randomUUID(); map.put(UUID_TAG, uuid); Bundle args = new Bundle(); fragment.setArguments(args); map.put(FRAGMENT, fragment); indicatorView.setBackgroundColor(Color.GRAY); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1); indicatorView.setTag(uuid); mLinearLayout.addView(indicatorView, params); indicatorView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setIndicatorViewSelected(v); } }); map.put(TAB, indicatorView); mArrayList.add(map); } private void setIndicatorViewSelected(View v) { UUID uuid = (UUID) v.getTag(); for (int i = 0; i < mArrayList.size(); i++) { HashMap<String, Object> map = mArrayList.get(i); if (uuid == map.get(UUID_TAG)) { set(i); } } } private final void delete(int pos) { UUID uuid = (UUID) mArrayList.get(pos).get(UUID_TAG); View view = mLinearLayout.findViewWithTag(uuid); mLinearLayout.removeView(view); mArrayList.remove(pos); mPagerAdapter.notifyDataSetChanged(); } private void setIndicatorViewSelectedColor(int pos) { for (int i = 0; i < mArrayList.size(); i++) { HashMap<String, Object> map = mArrayList.get(i); View view = (View) map.get(TAB); if (i == pos) view.setBackgroundColor(Color.RED); else view.setBackgroundColor(Color.GRAY); } } private void set(int pos) { mViewPager.setCurrentItem(pos, true); setIndicatorViewSelectedColor(pos); } private class MyFragmentPagerAdapter extends FragmentStatePagerAdapter { public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int pos) { return (Fragment) mArrayList.get(pos).get(FRAGMENT); } @Override public int getItemPosition(Object object) { return FragmentPagerAdapter.POSITION_NONE; } @Override public int getCount() { return mArrayList.size(); } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); Log.d(this.getClass().getName(), "notifyDataSetChanged"); } } private void onActionAdd() { add(getFragmentAt(mPagerAdapter.getCount()), getIndicatorAt(mPagerAdapter.getCount())); mPagerAdapter.notifyDataSetChanged(); } private void onActionDelete() { delete(mViewPager.getCurrentItem()); set(mViewPager.getCurrentItem()); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_add: onActionAdd(); break; case R.id.action_dele: onActionDelete(); break; default: break; } return super.onOptionsItemSelected(item); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.main, menu); } }
ViewPagerAndFragmentTabHost.java需要的viewpager_fragment.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <FrameLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> <LinearLayout android:id="@+id/indicator_LinearLayout" android:layout_width="match_parent" android:layout_height="50dip" android:orientation="horizontal" > </LinearLayout> </LinearLayout>
res\menu\main.xml文件:
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_add" android:orderInCategory="100" android:showAsAction="never" android:title="添加"/> <item android:id="@+id/action_dele" android:orderInCategory="100" android:showAsAction="never" android:title="删除"/> </menu>