Android Studio - 第四十八期 模块ViewPager+Fragment
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Studio - 第四十八期 模块ViewPager+Fragment相关的知识,希望对你有一定的参考价值。
最近一直在review撸撸的代码,发现了一种模块的写法,非常不错,独立出来,希望能帮到你~
如果你遇到这样的页面,怎么办,不会把所有代码都写到一个页面中吧~,这样看你代码的人会骂死你的吧~我想~而且如果不同的版本要用不同的位置,大小也不一样,难道你要重新布局嘛~这都是开发中需要纠结的,下面就开始正题了,这是利用了以前讲过的多版本打版以及配置多Fragment加载巧妙的解决了复杂的页面逻辑,我数了数,首页代码不到一百行,厉害吧~哈哈哈哈~
在写这样的页面之前给大家介绍一下怎么写一个页面模块代码。
demo1:单Activity页面多模块单版本
Demo1FragmentFactory:
package com.example.p031_mokuaihua_viewpager_fragment.demo1.factorys; import android.support.v4.util.SparseArrayCompat; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo1.fragments.Demo1Fragment1; import com.example.p031_mokuaihua_viewpager_fragment.demo1.fragments.Demo1Fragment2; /** * Created by shining on 2017/2/27 0027. */ public class Demo1FragmentFactory { private static SparseArrayCompat<Class<? extends BaseFragment>> sIndexFragments = new SparseArrayCompat<>(); static { sIndexFragments.put(R.id.demo1_page_0_item_0, Demo1Fragment1.class);//模块1 sIndexFragments.put(R.id.demo1_page_0_item_1, Demo1Fragment2.class);//模块2 } public static Class<? extends BaseFragment> get(int id) { if (sIndexFragments.indexOfKey(id) < 0) { throw new UnsupportedOperationException("cannot find fragment by " + id); } return sIndexFragments.get(id); } public static SparseArrayCompat<Class<? extends BaseFragment>> get() { return sIndexFragments; } }
ComFragmentHelper:
package com.example.p031_mokuaihua_viewpager_fragment.utils; import android.os.Bundle; import android.support.v4.app.Fragment; /** * Created by shining on 2016/12/21 0021. */ public class ComFragmentHelper { /** * 新建fragment实例 * @param fragmentKlass * @param bundle * @param <T> * @return */ @SuppressWarnings("unchecked") public static <T extends Fragment> T newFragment(Class<T> fragmentKlass, Bundle bundle) { T res = null; try { res = fragmentKlass.newInstance(); if (bundle != null) { res.setArguments(bundle); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return res; } /** * 根据fragment的完整包名+名称实例化fragment * @param className * @param bundle * @param <T> * @return */ @SuppressWarnings("unchecked") public static <T extends Fragment> T newFragment(String className, Bundle bundle) { T res = null; try { res = (T) Class.forName(className).newInstance(); if (bundle != null) { res.setArguments(bundle); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return res; } }
Demo1Fragment1:
package com.example.p031_mokuaihua_viewpager_fragment.demo1.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexNetFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo1.Demo1Activity; /** * Created by shining on 2017/8/14. */ public class Demo1Fragment1 extends BaseIndexNetFragment { @Override public void call(Object value) { } @Override protected int getLayoutId() { return R.layout.activity_demo1_fragment1; } @Override protected void setup(View rootView, @Nullable Bundle savedInstanceState) { super.setup(rootView, savedInstanceState); rootView.findViewById(R.id.tv1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SendToFragment("demo1的fragment1页面"); } }); } /** * 页面传值操作部分 * * @param id1 */ private void SendToFragment(String id1) { //举例 // IndexFoodFragmentUpdateIds iff = new IndexFoodFragmentUpdateIds(); // iff.setFood_definition_id(id1); // iff.setFood_name(id2); if (getActivity() != null && getActivity() instanceof Demo1Activity) { ((Demo1Activity) getActivity()).callFragment(id1, Demo1Fragment2.class.getName()); } } }
Demo1Fragment2:
package com.example.p031_mokuaihua_viewpager_fragment.demo1.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexNetFragment; import com.example.p031_mokuaihua_viewpager_fragment.utils.ToastUtil; /** * Created by shining on 2017/8/14. */ public class Demo1Fragment2 extends BaseIndexNetFragment { @Override public void call(Object value) { String ids = (String) value; ToastUtil.showToastShort(ids); } @Override protected int getLayoutId() { return R.layout.activity_demo1_fragment2; } @Override protected void setup(View rootView, @Nullable Bundle savedInstanceState) { super.setup(rootView, savedInstanceState); } }
这里注意Fragment之间如果需要通信,可以用下面的方法:
/** * 页面传值操作部分 * * @param id1 */ private void SendToFragment(String id1) { //举例 // IndexFoodFragmentUpdateIds iff = new IndexFoodFragmentUpdateIds(); // iff.setFood_definition_id(id1); // iff.setFood_name(id2); if (getActivity() != null && getActivity() instanceof Demo1Activity) { ((Demo1Activity) getActivity()).callFragment(id1, Demo1Fragment2.class.getName()); } } //接收传值处理逻辑bufen @Override public void call(Object value) { String ids = (String) value; ToastUtil.showToastShort(ids); }
Demo1Activity:
package com.example.p031_mokuaihua_viewpager_fragment.demo1; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.util.SparseArrayCompat; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseActivity; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo1.factorys.Demo1FragmentFactory; import com.example.p031_mokuaihua_viewpager_fragment.utils.ComFragmentHelper; public class Demo1Activity extends BaseActivity implements OnClickListener { @Override protected int getLayoutId() { return R.layout.activity_demo1; } @Override protected void setup(@Nullable Bundle savedInstanceState) { super.setup(savedInstanceState); findview(); onclickListener(); doNetWork(); } private void doNetWork() { } private void onclickListener() { } private void findview() { setupFragments(); } /** * 初始化首页fragments */ private void setupFragments() { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); SparseArrayCompat<Class<? extends BaseFragment>> array = Demo1FragmentFactory.get();//一个版本模式bufen int size = array.size(); BaseFragment item; for (int i = 0; i < size; i++) { item = ComFragmentHelper.newFragment(array.valueAt(i), null); ft.replace(array.keyAt(i), item, item.getClass().getName()); } ft.commitAllowingStateLoss(); } @Override public void onClick(View v) { } /** * fragment间通讯bufen * * @param value 要传递的值 * @param tag 要通知的fragment的tag */ public void callFragment(Object value, String... tag) { FragmentManager fm = getSupportFragmentManager(); Fragment fragment; for (String item : tag) { if (TextUtils.isEmpty(item)) { continue; } fragment = fm.findFragmentByTag(item); if (fragment != null && fragment instanceof BaseIndexFragment) { ((BaseIndexFragment) fragment).call(value); } } } }
效果如下图:
demo2:单Activity页面多模块多版本
Demo2Config1:
package com.example.p031_mokuaihua_viewpager_fragment.demo2.configs; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.support.v4.util.SparseArrayCompat; import android.text.TextUtils; import com.example.p031_mokuaihua_viewpager_fragment.applications.DemoApplication; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.utils.MyLogUtil; /** * <p>function: </p> * <p>description: </p> * <p>history: 1. 2017/3/23</p> * <p>Author: geek</p> * <p>modification:</p> */ public class Demo2Config1 { private static final String INDEX_META_DATA = "DEMO2_CONFIG"; /** viewpager页大小*/ // public static int PAGE_COUNT; /** viewpager每页的itemview id*/ // public static String PAGE_ID; /** 默认显示第几页*/ // public static int DEFAULT_PAGE_INDEX; /** * fragment配置 */ private static SparseArrayCompat<Class<? extends BaseFragment>> sIndexFragments = new SparseArrayCompat<>(); public static void config() { Context ctx = DemoApplication.get(); ApplicationInfo info = null; try { info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if (info == null) { throw new UnsupportedOperationException(); } String klassName = info.metaData.getString(INDEX_META_DATA); if (TextUtils.isEmpty(klassName)) { throw new UnsupportedOperationException("please config " + INDEX_META_DATA + " value"); } if (klassName.startsWith(".")) { klassName = DemoApplication.get().getPackageName() + klassName; } MyLogUtil.d("geek", klassName); try { Class<?> klass = Class.forName(klassName); klass.getDeclaredMethod("setup").invoke(null); } catch (Exception e) { e.printStackTrace(); } } public static Class<? extends BaseFragment> getFragment(int id) { if (sIndexFragments.indexOfKey(id) < 0) { throw new UnsupportedOperationException("cannot find fragment by " + id); } return sIndexFragments.get(id); } public static SparseArrayCompat<Class<? extends BaseFragment>> getFragments() { return sIndexFragments; } }
Demo2Factory1:
package com.example.p031_mokuaihua_viewpager_fragment.demo2.factorys; import android.support.v4.util.SparseArrayCompat; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo2.configs.Demo2Config1; import com.example.p031_mokuaihua_viewpager_fragment.demo2.fragments.Demo2Fragment1; import com.example.p031_mokuaihua_viewpager_fragment.demo2.fragments.Demo2Fragment2; public class Demo2Factory1 { public static void setup() { // IndexConfig.PAGE_COUNT = 3; // IndexConfig.PAGE_ID = "old_pager_index_"; // IndexConfig.DEFAULT_PAGE_INDEX = 1; registerFragments(Demo2Config1.getFragments()); } private static void registerFragments(SparseArrayCompat<Class<? extends BaseFragment>> sIndexFragments) { sIndexFragments.put(R.id.demo2_page_0_item_1, Demo2Fragment1.class);//菜谱 sIndexFragments.put(R.id.demo2_page_0_item_2, Demo2Fragment2.class);//视频 } }
build.gradle:(多版本打版)
def currentMode = flavor.versionName.split("_")[3] def currentEnvironment = flavor.versionName.split("_")[1] def stValue = true // t == currentEnvironment 以前的判断条件 if (currentEnvironment.endsWith("T")) {//判断是否为测试版 是否以T结尾 stValue = false } else { stValue = true } if (currentMode == demo1) { flavor.manifestPlaceholders = [DEMO2_CONFIG_VALUE: ".demo2.factorys.Demo2Factory1", STATISTICS_VALUE: stValue] } else if (currentMode == demo2) { flavor.manifestPlaceholders = [DEMO2_CONFIG_VALUE: ".demo2.factorys.Demo2Factory2", STATISTICS_VALUE: stValue] }
Demo2Activity:
package com.example.p031_mokuaihua_viewpager_fragment.demo2; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.util.SparseArrayCompat; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.applications.ConstantNetUtil; import com.example.p031_mokuaihua_viewpager_fragment.applications.NetConfig; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseActivity; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo2.configs.Demo2Config1; import com.example.p031_mokuaihua_viewpager_fragment.demo2.configs.Demo2Config2; import com.example.p031_mokuaihua_viewpager_fragment.utils.ComFragmentHelper; public class Demo2Activity extends BaseActivity implements OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) { Demo2Config1.config(); } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) { Demo2Config2.config(); } super.onCreate(savedInstanceState); setupFragments(); findview(); onclickListener(); doNetWork(); } @Override protected int getLayoutId() { return R.layout.activity_demo2; } @Override protected void setup(@Nullable Bundle savedInstanceState) { super.setup(savedInstanceState); // setupFragments(); // findview(); // onclickListener(); // doNetWork(); } /** * 初始化首页fragments */ private void setupFragments() { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); //TODO 多版本模式bufen SparseArrayCompat<Class<? extends BaseFragment>> array = which_version_fragment_config();// int size = array.size(); BaseFragment item; for (int i = 0; i < size; i++) { item = ComFragmentHelper.newFragment(array.valueAt(i), null); ft.replace(array.keyAt(i), item, item.getClass().getName()); } ft.commitAllowingStateLoss(); } private SparseArrayCompat<Class<? extends BaseFragment>> which_version_fragment_config() { if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) { return Demo2Config1.getFragments(); } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) { return Demo2Config2.getFragments(); } return Demo2Config1.getFragments(); } private void doNetWork() { } private void onclickListener() { } private void findview() { } @Override public void onClick(View v) { } /** * fragment间通讯bufen * * @param value 要传递的值 * @param tag 要通知的fragment的tag */ public void callFragment(Object value, String... tag) { FragmentManager fm = getSupportFragmentManager(); Fragment fragment; for (String item : tag) { if (TextUtils.isEmpty(item)) { continue; } fragment = fm.findFragmentByTag(item); if (fragment != null && fragment instanceof BaseIndexFragment) { ((BaseIndexFragment) fragment).call(value); } } } }
效果如下图:
下面就是最复杂的一种需求:demo3 单Activity页面多模块单版本两个Viewpager
Demo3Config:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.configs; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.support.v4.util.SparseArrayCompat; import android.text.TextUtils; import com.example.p031_mokuaihua_viewpager_fragment.applications.DemoApplication; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.utils.MyLogUtil; public class Demo3Config { private static final String INDEX_META_DATA = "DEMO3_CONFIG"; /** viewpager页大小*/ public static int PAGE_COUNT; /** viewpager每页的itemview id*/ public static String PAGE_LAYOUT_ID; /** 默认显示第几页*/ public static int DEFAULT_PAGE_INDEX; /** * fragment配置 */ private static SparseArrayCompat<Class<? extends BaseFragment>> sIndexFragments = new SparseArrayCompat<>(); public static void config() { Context ctx = DemoApplication.get(); ApplicationInfo info = null; try { info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if (info == null) { throw new UnsupportedOperationException(); } String klassName = info.metaData.getString(INDEX_META_DATA); if (TextUtils.isEmpty(klassName)) { throw new UnsupportedOperationException("please config " + INDEX_META_DATA + " value"); } if (klassName.startsWith(".")) { klassName = DemoApplication.get().getPackageName() + klassName; } MyLogUtil.d("geek", klassName); try { Class<?> klass = Class.forName(klassName); klass.getDeclaredMethod("setup").invoke(null); } catch (Exception e) { e.printStackTrace(); } } public static Class<? extends BaseFragment> getFragment(int id) { if (sIndexFragments.indexOfKey(id) < 0) { throw new UnsupportedOperationException("cannot find fragment by " + id); } return sIndexFragments.get(id); } public static SparseArrayCompat<Class<? extends BaseFragment>> getFragments() { return sIndexFragments; } }
Demo3Factory:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.factorys; import android.support.v4.util.SparseArrayCompat; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo3.configs.Demo3Config; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment10; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment11; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment20; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment21; /** * 首页模块fragment的工厂, 首页模块有需要更换的,可以在此修改,格式为id->Fragment.class<br /> * Created by shining on 2016/8/1. */ public class Demo3Factory { public static void setup() { Demo3Config.PAGE_COUNT = 2; Demo3Config.PAGE_LAYOUT_ID = "activity_demo3_layout_pager_item_"; Demo3Config.DEFAULT_PAGE_INDEX = 0; registerFragments(Demo3Config.getFragments()); } private static void registerFragments(SparseArrayCompat<Class<? extends BaseFragment>> sIndexFragments) { sIndexFragments.put(R.id.fragment_demo3_pager_index_0_0, Demo3Fragment10.class);//第一屏 layout1 sIndexFragments.put(R.id.fragment_demo3_pager_index_0_1, Demo3Fragment11.class);//第一屏 layout2 sIndexFragments.put(R.id.fragment_demo3_pager_index_1_0, Demo3Fragment20.class);//第二屏 layout1 sIndexFragments.put(R.id.fragment_demo3_pager_index_1_1, Demo3Fragment21.class);//第二屏 layout2 } }
Demo3Fragment10:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexNetFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo3.Demo3Activity; /** * Created by shining on 2017/8/14. */ public class Demo3Fragment10 extends BaseIndexNetFragment { private Context mContext; @Override public void onCreate(@Nullable Bundle bundle) { super.onCreate(bundle); mContext = getActivity(); } @Override public void call(Object value) { } @Override protected int getLayoutId() { return R.layout.activity_demo3_fragment10; } @Override protected void setup(View rootView, @Nullable Bundle savedInstanceState) { super.setup(rootView, savedInstanceState); rootView.findViewById(R.id.tv1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SendToFragment("demo3的fragment1页面"); ((Demo3Activity) mContext).changeView(1); } }); } /** * 页面传值操作部分 * * @param id1 */ private void SendToFragment(String id1) { //举例 // IndexFoodFragmentUpdateIds iff = new IndexFoodFragmentUpdateIds(); // iff.setFood_definition_id(id1); // iff.setFood_name(id2); if (getActivity() != null && getActivity() instanceof Demo3Activity) { ((Demo3Activity) getActivity()).callFragment(id1, Demo3Fragment20.class.getName()); } } }
Demo3Fragment20:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseIndexNetFragment; import com.example.p031_mokuaihua_viewpager_fragment.utils.ToastUtil; /** * Created by shining on 2017/8/14. */ public class Demo3Fragment20 extends BaseIndexNetFragment { @Override public void call(Object value) { String ids = (String) value; ToastUtil.showToastShort(ids); } @Override protected int getLayoutId() { return R.layout.activity_demo3_fragment20; } @Override protected void setup(View rootView, @Nullable Bundle savedInstanceState) { super.setup(rootView, savedInstanceState); } }
这里的导航点也可以自定义:给大家提供一个util 有圆的 方的 长方形 水滴
IndexPagerIndicator:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.utils; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.ViewPager; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import com.example.p031_mokuaihua_viewpager_fragment.R; /** * 首页viewpager指示符<br/> * Created by geek on 2016/7/29. */ public class IndexPagerIndicator extends LinearLayout { private int mItemWidth; private int mItemSelectedHeight; private int mItemInterval; private int mItemColor; private int mStartX; private int mCurrentX; private Paint mSelectedPaint; private IStyleDrawer mStyleDrawer; public IndexPagerIndicator(Context context) { this(context, null, 0); } public IndexPagerIndicator(Context context, AttributeSet attrs) { this(context, attrs, 0); } public IndexPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setBackgroundColor(Color.TRANSPARENT); setOrientation(LinearLayout.HORIZONTAL); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndexPagerIndicator, defStyleAttr, 0); mItemWidth = ta.getDimensionPixelSize(R.styleable.IndexPagerIndicator_indicator_width, 10); int itemHeight = ta.getDimensionPixelSize(R.styleable.IndexPagerIndicator_indicator_height, 2); mItemSelectedHeight = ta.getDimensionPixelSize(R.styleable.IndexPagerIndicator_indicator_select_height, 0); if (mItemSelectedHeight == 0) { mItemSelectedHeight = itemHeight;} mItemInterval = ta.getDimensionPixelSize(R.styleable.IndexPagerIndicator_indicator_interval, 0); mItemColor = ta.getColor(R.styleable.IndexPagerIndicator_indicator_item_color, Color.BLACK); int selectedColor = ta.getColor(R.styleable.IndexPagerIndicator_indicator_select_color, Color.WHITE); String styleDrawer = ta.getString(R.styleable.IndexPagerIndicator_indicator_style_drawer); try { if (TextUtils.isEmpty(styleDrawer)) { throw new Exception(); } mStyleDrawer = (IStyleDrawer) Class.forName(styleDrawer).newInstance(); } catch (Exception e) { e.printStackTrace(); mStyleDrawer = new DefaultStyleDrawer(); } ta.recycle(); mStyleDrawer.prepare(mItemWidth, itemHeight, mItemSelectedHeight); mSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mSelectedPaint.setColor(selectedColor); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mItemSelectedHeight > getMeasuredHeight()) { setMeasuredDimension(getMeasuredWidth(), mItemSelectedHeight); } mStartX = (getMeasuredWidth() - (getChildCount() * mItemWidth + (getChildCount() - 1) * mItemInterval)) / 2; if (mCurrentX == 0) { mCurrentX = mStartX; } } @Override public void draw(Canvas canvas) { super.draw(canvas); canvas.save(); canvas.translate(mCurrentX, (getMeasuredHeight() - mItemSelectedHeight) / 2); mStyleDrawer.draw(canvas, mSelectedPaint); canvas.restore(); } @Override protected Parcelable onSaveInstanceState() { Parcelable p = super.onSaveInstanceState(); Bundle bundle = new Bundle(); bundle.putInt("current", mCurrentX); bundle.putParcelable("state", p); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { Bundle bundle = (Bundle) state; mCurrentX = bundle.getInt("current"); state = bundle.getParcelable("state"); } super.onRestoreInstanceState(state); } public void setupWithViewPager(ViewPager pager) { if (pager.getAdapter() == null) { throw new UnsupportedOperationException("your viewpager must set adapter first"); } create(pager.getAdapter().getCount()); pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { mCurrentX = (int) (mStartX + (mItemWidth + mItemInterval) * (position + positionOffset)); invalidate(); } @Override public void onPageSelected(int position) { mCurrentX = mStartX + (mItemWidth + mItemInterval) * position; invalidate(); } @Override public void onPageScrollStateChanged(int state) { } }); } private void create(int count) { removeAllViews(); View itemView; for (int i = 0; i < count - 1; i++) { itemView = buildView(mItemInterval); setOnClick(itemView, i); addView(itemView); } itemView = buildView(0); setOnClick(itemView, count - 1); addView(itemView); } private void setOnClick(View itemView, final int pos) { itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mListener != null) { mListener.onItemClick(pos);} } }); } private View buildView(int margin) { return mStyleDrawer.buildView(getContext(), mItemColor, margin); } private OnItemClickListener mListener; public void setOnItemClickListener(OnItemClickListener li) { mListener = li; } public interface OnItemClickListener { void onItemClick(int pos); } public interface IStyleDrawer { void prepare(int itemWidth, int itemHeight, int selectedHeight); void draw(Canvas canvas, Paint paint); View buildView(Context ctx, int bgColor, int margin); } public static class DefaultStyleDrawer implements IStyleDrawer { private Rect mRect; private int mItemWidth; private int mItemHeight; @Override public void prepare(int itemWidth, int itemHeight, int selectedHeight) { mItemWidth = itemWidth; mItemHeight = itemHeight; mRect = new Rect(0, 0, itemWidth, selectedHeight); } @Override public void draw(Canvas canvas, Paint paint) { canvas.drawRect(mRect, paint); } @Override public View buildView(Context ctx, int bgColor, int margin) { View view = new View(ctx); view.setBackgroundColor(bgColor); LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(mItemWidth, mItemHeight); if (margin != 0) { p.rightMargin = margin;} view.setLayoutParams(p); return view; } } }
NoScrollViewPager:
/** * Copyright 2015, Smart Haier * All rights reserved. * Description: 没有滑屏效果的ViewPager * Author: geyanyan * Date: 2016/11/18 * FileName: TabFragmentAdapter.java * History: * 1. Date:2016/11/21 21:45 * Author:geyanyan * Modification: */ package com.example.p031_mokuaihua_viewpager_fragment.demo3.utils; import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; public class NoScrollViewPager extends ViewPager { public NoScrollViewPager(Context context) { super(context); } public NoScrollViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent ev) { return false; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } }
ViewPagerChangeAdapter:
package com.example.p031_mokuaihua_viewpager_fragment.demo3.utils; import android.support.v4.view.ViewPager; /** * <p>function: </p> * <p>description: </p> * <p>history: 1. 2016/12/13</p> * <p>Author: geek</p> * <p>modification:</p> */ public class ViewPagerChangeAdapter implements ViewPager.OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { } }
Demo3Activity:
package com.example.p031_mokuaihua_viewpager_fragment.demo3; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.util.SparseArrayCompat; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import com.example.p031_mokuaihua_viewpager_fragment.R; import com.example.p031_mokuaihua_viewpager_fragment.base.BaseFragment; import com.example.p031_mokuaihua_viewpager_fragment.demo3.configs.Demo3Config; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment10; import com.example.p031_mokuaihua_viewpager_fragment.demo3.fragments.Demo3Fragment20; import com.example.p031_mokuaihua_viewpager_fragment.demo3.utils.IndexPagerIndicator; import com.example.p031_mokuaihua_viewpager_fragment.demo3.utils.ViewPagerChangeAdapter; import com.example.p031_mokuaihua_viewpager_fragment.utils.ComFragmentHelper; import com.example.p031_mokuaihua_viewpager_fragment.utils.MyLogUtil; import java.util.List; import static com.example.p031_mokuaihua_viewpager_fragment.demo3.configs.Demo3Config.PAGE_COUNT; public class Demo3Activity extends FragmentActivity implements OnClickListener { private ViewPager mViewPager; private IndexPagerIndicator mIndicator; //当前选中的项 private int currenttab = -1; // private static final int PAGE_COUNT = 2; // private static final String PAGE_LAYOUT_ID = "demo3_layout_pager_item_"; private Demo3Fragment10 oneFragment; private Demo3Fragment20 twoFragment; /** * 页面集合 */ List<Fragment> fragmentList; private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { Demo3Config.config(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo3); mContext = Demo3Activity.this; findview(); addListener(); doNetWork(); } private void doNetWork() { setupViewPager(); setupFragments(); // fragmentList = new ArrayList<Fragment>(); // oneFragment = new ShezhimimaOneFragment(); // twoFragment = new ShezhimimaTwoFragment(); // // fragmentList.add(oneFragment); // fragmentList.add(twoFragment); // mViewPager.setAdapter(new MyFrageStatePagerAdapter(getSupportFragmentManager())); } private void setupViewPager() { mViewPager.setOffscreenPageLimit(Demo3Config.PAGE_COUNT); mViewPager.setAdapter(new IndexPagerAdapter()); mIndicator.setupWithViewPager(mViewPager); mIndicator.setOnItemClickListener(new IndexPagerIndicator.OnItemClickListener() { @Override public void onItemClick(int pos) { mViewPager.setCurrentItem(pos); } }); mViewPager.addOnPageChangeListener(new ViewPagerChangeAdapter() { @Override public void onPageSelected(int position) { if (position == 0) { // MobEventHelper.onEvent(Demo3Activity.this, "UI2_index_personal_center");//统计 } } }); mViewPager.setCurrentItem(Demo3Config.DEFAULT_PAGE_INDEX);//设置当前显示标签页为第一页 } /** * 初始化首页fragments */ private void setupFragments() { // 使用HierarchyChangeListener的目的是防止在viewpager的itemview还没有准备好就去inflateFragment // 带来的问题 mViewPager.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { @Override public void onChildViewAdded(View parent, View child) { if (((ViewGroup) parent).getChildCount() < PAGE_COUNT) { return; } FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); SparseArrayCompat<Class<? extends BaseFragment>> array = Demo3Config.getFragments(); int size = array.size(); BaseFragment item; for (int i = 0; i < size; i++) { item = ComFragmentHelper.newFragment(array.valueAt(i), null); ft.replace(array.keyAt(i), item, item.getClass().getName()); } ft.commitAllowingStateLoss(); } @Override public void onChildViewRemoved(View parent, View child) { } }); } private void addListener() { } private void findview() { mViewPager = (ViewPager) findViewById(R.id.viewpager_my); mIndicator = (IndexPagerIndicator) findViewById(R.id.indicator); } @Override public void onClick(View v) { } /** * 首页viewpager adapter */ public class IndexPagerAdapter extends PagerAdapter { @Override public int getCount() { return 2; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { MyLogUtil.d(Demo3Config.PAGE_LAYOUT_ID + position); int layoutId = getResources().getIdentifier(Demo3Config.PAGE_LAYOUT_ID + position, "layout", getPackageName()); if (layoutId == 0) { throw new UnsupportedOperationException("layout not found!"); } View itemLayout = LayoutInflater.from(Demo3Activity.this).inflate(layoutId, container, false); container.addView(itemLayout); return itemLayout; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } /** * 定义自己的ViewPager适配器。 * 也可以使用FragmentPagerAdapter。关于这两者之间的区别,可以自己去搜一下。 */ public class MyFrageStatePagerAdapter extends FragmentStatePagerAdapter { public MyFrageStatePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return fragmentList.size(); } /** * 每次更新完成ViewPager的内容后,调用该接口,此处复写主要是为了让导航按钮上层的覆盖层能够动态的移动 */ @Override public void finishUpdate(ViewGroup container) { super.finishUpdate(container);//这句话要放在最前面,否则会报错 //获取当前的视图是位于ViewGroup的第几个位置,用来更新对应的覆盖层所在的位置 int currentItem = mViewPager.getCurrentItem(); if (currentItem == currenttab) { return; } currenttab = mViewPager.getCurrentItem(); } } //手动设置ViewPager要显示的视图 public void changeView(int desTab) { mViewPager.setCurrentItem(desTab, true); } // public IndexViewPager getViewPager() { // return mViewPager; // } /** * fragment间通讯bufen * * @param value 要传递的值 * @param tag 要通知的fragment的tag */ public void callFragment(Object value, String... tag) { FragmentManager fm = getSupportFragmentManager(); Fragment fragment; for (String item : tag) { if (TextUtils.isEmpty(item)) { continue; } fragment = fm.findFragmentByTag(item); if (fragment != null && fragment instanceof BaseFragment) { ((BaseFragment) fragment).call(value); } } } }
效果如下图:
总结:遇到新的需求,并且很复杂的时候,多想想,多总结一下原生的写法,你会发现有更简单的方法这样下次会节省你近80%的时间,如果你一直都是老的写法,需求却在变,你就会落后,效率就低了,这才是架构师高薪的原因,善于总结,并不是多牛逼~相信上面的方案能给你启发,提前祝大家周末快乐~看杀破狼吧~周末~约嘛~
地址:https://github.com/geeklx/MyApplication/tree/master/p031_mokuaihua_viewpager_fragment
另附图:传火嘛~
本文出自 “梁肖技术中心” 博客,请务必保留此出处http://liangxiao.blog.51cto.com/3626612/1957026
以上是关于Android Studio - 第四十八期 模块ViewPager+Fragment的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio 第七十八期 - Android下拉悬停collapsinglayout
Android Studio 第五十八期 - Android屏幕亮度与休眠
Android Studio 第六十八期 - Android8.0 进程保活
Android Studio第三十八期 - HIOS跳转协议解决URI跳转原生页面并传递参数