最近一直在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:
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
另附图:传火嘛~