ViewPager(懒加载)+Fragment+自定义View

主界面的UI与设计

现在一般的项目都是底部几个按钮对应这几个fragment这种情况,这种大体上可以有2种写法

  1. FragmentTabHost/(RadiuGroup+RadiuButton)等等一些底部按钮+Fragment来展示
  2. 一些底部按钮+ViewPager+Fragment来实现

这两种我个人更喜欢使用的是第二种,并且在最近的项目中也是用第二种方式来实现的,如果产品说底部按钮对应的页面是不能够滑动的,那么两种没什么区别,(viewPager可以禁止滑动来实现)可后来如果产品又说需要滑动了,那如果用第一种实现的就傻了,而第二种默认就是可以滑动的只需要简单的修改一下就可以

public class ViewPagerMain extends ViewPager{
    private boolean mIsScroll=true;//通过这个值来判断是否需要禁止滑动

    public ViewPagerMain(Context context) {
        super(context);
    }

    public ViewPagerMain(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mIsScroll==true){
            return super.onInterceptTouchEvent(ev);
        }else{
            return mIsScroll;
        }


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mIsScroll==true){
            return super.onTouchEvent(ev);
        }else{
            return mIsScroll;
        }

    }

    public void setIsScroll(boolean isScroll){
        mIsScroll = isScroll;
    }
}

至于底部的那些按钮我并没有使用上面的一些Android原生控件,而是通过
布局文件自己摆放,我个人认为这样的话扩展性更高一些,当然这只是一部分原因后面的代码大家可以看到这么写的好处
底部xml


    
        
            
            
        

    
    
        
        
    
    

        

        

    
    
        
        

    
    
        
        
    




/**
 * 监听底部按钮的切换状态,mMainBottomRoot为底部按钮的根布局,这样封装的话如果底部按钮的数量有变动
 * 这段代码不用发生什么变动,而且下一个项目用到的话直接复制粘贴
private void setBottomListener() {
    int childCount = mMainBottomRoot.getChildCount();
    for (int i = 0; i 

至于Fragment 我这里对Fragment展示的布局做了进一步封装,因为现在项目的主界面大体上不外呼刚进来时候弹个ProgressBar,DialogFragmen等与用户进行交互,当数据请求回来再隐藏销毁,如果数据请求失败再展示个失败的界面
这里我对它又进行了一次封装,不仅减少了代码的书写也加强了扩展性和维护性
/**
* BaseFragment
*/

public abstract class MyBaseFragment extends Fragment {

    protected Context context;
    protected StateLayout stateLayout;
    protected boolean isFirst = true;
    protected boolean isPrepared;
    private Unbinder mUnbinder;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        context = getActivity();
        //防止Fragment重复加载
        if (stateLayout == null) {
            // 说明这个Fragemnt的onCreateView方法是第一次执行
            View view = getContentView();
            mUnbinder = ButterKnife.bind(this, view);
            //对Fragment展示的布局进一步封装
            stateLayout = StateLayout.newInstance(context, view);
            initView();
            initListener();
            //
            isPrepared = true;
        } else {
            ViewGroup parent = (ViewGroup) stateLayout.getParent();
            if (parent != null) {
                parent.removeView(stateLayout);
            }
        }
        return stateLayout;
    }


    /** * Fragment当前状态是否可见 */
    protected boolean isVisible;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {
            isVisible = true;
            LogUtil.e(getClass().getName()+"__________setUserVisibleHint");
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        LogUtil.e(getClass().getName()+"__________onResume");
        onVisible();
    }

    /** * 对initData再进一步的封装 */
    protected void onVisible() {
        //保证ViewPager能够实现懒加载的方式并保证只有第一次进入这个Fragment的时候才进行数据的加载
        LogUtil.e("isFirst _____________" + isFirst);
        LogUtil.e("isVisible _____________" + isVisible);
        LogUtil.e("isPrepared _____________" + isPrepared);
        if (!isFirst || !isVisible || !isPrepared) {
            return;
        }
        initData();
        isFirst = false;
    }


    /** * 不可见 */
    protected void onInvisible() {


    }


    /** * 查找View,增加这个方法是为了略强转 * * @param id * @return */
    @SuppressWarnings("unchecked")
    public  T findView(int id) {
        T view = (T) stateLayout.findViewById(id);
        return view;
    }




    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mUnbinder!=null){
            mUnbinder.unbind();
        }

    }

    /** * 返回Fragment自己的名称 */
    protected  CharSequence getTitle(){
        return getClass().getName();
    };

    /** * 初始化View相关的代码写在这个方法中 */
    public abstract void initView();

    /** * 初始化Listener的代码写在这个方法中 */
    public abstract void initListener();

    /** * 初始化数据的代码写在这个方法中 */
    public abstract void initData();

    /** * 返回正常的界面想要展示的View或View的Id */
    public abstract View getContentView();
}
public class StateLayout extends FrameLayout {

    private View loadingView;
    private View failView;
    private View emptyView;
    private View contentView;

    public StateLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /** * 创建一个StateLayout实现 * @param contentView 正常想要展示的View */
    public static StateLayout newInstance(Context context, View contentView) {
        StateLayout stateLayout = (StateLayout) LayoutInflater.from(context).inflate(R.layout.state_layout, null);
        stateLayout.contentView=contentView;
        // StateLayout inflate之后就有3个状态的View了,还需要第四种状态
        stateLayout.addView(contentView);
        //当添加完成后暂时给隐藏掉
        contentView.setVisibility(View.GONE);
        return stateLayout;
    }



    /** * 渲染完毕后展示获取view对象 */
    @Override
    protected void onFinishInflate() {
        loadingView = findViewById(R.id.loadingView);
        failView = findViewById(R.id.failView);
        emptyView = findViewById(R.id.emptyView);

        showLoadingView();
    }

    /** 显示正在加载的View */
    public void showLoadingView() {
        showView(loadingView);
    }

    /** 显示失败的View */
    public void showFailView() {
        showView(failView);
    }

    /** 显示加载为空的View */
    public void showEmptyView() {
        showView(emptyView);
    }

    /** 显示正常界面的View */
    public void showContentView() {
        showView(contentView);
    }

    /** * 显示指定的View,并且隐藏其它的View * @param view 指定要显示的View */
    private void showView(View view) {

        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i); //
            child.setVisibility(view == child ? View.VISIBLE : View.GONE);
        }
    }

}

具体的我就不细说了,
有需要的话可以
下来看看https://github.com/wangrun1992/MainUiFrame

你可能感兴趣的:(viewpager,ui)