您现在的位置是:首页 > 文章详情

Android Studio - 第四十八期 模块ViewPager+Fragment

日期:2017-08-17点击:496

    最近一直在review撸撸的代码,发现了一种模块的写法,非常不错,独立出来,希望能帮到你~

    如果你遇到这样的页面,怎么办,不会把所有代码都写到一个页面中吧~,这样看你代码的人会骂死你的吧~我想~而且如果不同的版本要用不同的位置,大小也不一样,难道你要重新布局嘛~这都是开发中需要纠结的,下面就开始正题了,这是利用了以前讲过的多版本打版以及配置多Fragment加载巧妙的解决了复杂的页面逻辑,我数了数,首页代码不到一百行,厉害吧~哈哈哈哈~

    wKiom1mVCGDgc4wXAAd80q3MBKY495.png

    wKiom1mVCGThlG5pAAaTMwi2eqM158.png

    wKioL1mVCGeizJDrAAQFuW8yA9Y704.png

    在写这样的页面之前给大家介绍一下怎么写一个页面模块代码。

    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);             }         }     } }

    效果如下图:

    wKioL1mVC9qQ04r_AAWblJiT7A0307.gif

    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);             }         }     } }

    效果如下图:

    wKioL1mVDj6T2v-1AARlCOkAPj8669.gif

    下面就是最复杂的一种需求: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:

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);             }         }     } }

    效果如下图:

    wKiom1mVEDSQZmf2AAtvT2SFMmA085.gif

    总结:遇到新的需求,并且很复杂的时候,多想想,多总结一下原生的写法,你会发现有更简单的方法这样下次会节省你近80%的时间,如果你一直都是老的写法,需求却在变,你就会落后,效率就低了,这才是架构师高薪的原因,善于总结,并不是多牛逼~相信上面的方案能给你启发,提前祝大家周末快乐~看杀破狼吧~周末~约嘛~

    地址:https://github.com/geeklx/MyApplication/tree/master/p031_mokuaihua_viewpager_fragment

    另附图:传火嘛~

    wKioL1mVEi7DzU2UAAu8HwiB0fU560.png


原文链接:https://blog.51cto.com/liangxiao/1957026
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章