仿微信主页布局

先来看看微信整体布局方式及市面上一些常见的应用大致布局方式,几乎都是采用顶部或者底部一个菜单栏控制方式,然后中间一些内容显示界面,下面是微信应用、腾讯新闻和163网易邮箱应用的部分界面效果图,如下:

这里写图片描述
这里写图片描述
这里写图片描述
今天将对这种常见布局方式结合个人所做过的项目进行一个汇总,在最早出来工作之时,那时多数的人做这种应用是采用tabhost去实现的,tabhost可以根据项目需求选择性加载多张tab页,每一张的tab显示页都是一个activity,不过这种方式现在看来已经过时被淘汰了,现在的应用多数是采用activity碎片化方式去实现,即使用fragment组件来操作。那么这种做法的好处就是可以节约系统资源的开销。这个其实也很好理解,可以很简单的去理解,fragment是寄生在activity之上的,以上面的应用做法为例,若是使用传统做法tabhost去做的话,则需要加载好几个activity这种重量级组件,而使用fragment方式再加载界面时我们系统只需要加载一个重量级activity,然后再使用轻量级fragment控件即可实现。

下面是个人负责的一个车辆信息canbus项目,效果图如下:

这里写图片描述

这里写图片描述

这边跟上面几个应用做法不同的是,我这边是将菜单控制部分放在了左边显示,然后在切换菜单时去加载不同的界面,下面说说是怎么个做法去实现的。

逻辑分析:
这边分两种方式去实现:
方式一:通过fragment
java代码实现部分如下:
这里写图片描述
BaseFragment.java:

package com.asir.viewpagerandfragment.fragement;

import android.annotation.SuppressLint;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

@SuppressLint("NewApi")
public abstract class BaseFragment extends Fragment {
    protected View mViewRoot;
    protected Context mContext;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mViewRoot = initView(inflater);
        return mViewRoot;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData(savedInstanceState);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.mContext = this.getActivity();
    }

    public View getRootView() {
        return mViewRoot;
    }

    public abstract View initView(LayoutInflater inflater);

    public abstract void initData(Bundle savedInstanceState);


}

写一个父类fragment然后让所有的fragment都去继承这个父类接口,在子类中去实现父类的两个方法initView(),initdata()即可,例举一个子类代码实现:

package com.asir.viewpagerandfragment.fragement;

import com.asir.viewpagerandfragment.R;
import com.asir.viewpagerandfragment.adapter.CarTroubleCanACAdapter;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ListView;

public class CarTroubleCanACFragment extends BaseFragment {
    private CarTroubleCanACAdapter mCanACAdapter;
    private ListView mListView;
    // 空调故障列表数据
    private int[] mCarTroubleCanACInfos;
    public static final int mCurrFragmentID = 6;

    @Override
    public View initView(LayoutInflater inflater) {
        return (View) inflater.inflate(R.layout.list_view, null);
    }

    @Override
    public void initData(Bundle savedInstanceState) {
        String[] leftStr = mContext.getResources().getStringArray(R.array.car_trouble_item6_list_left);
        mCanACAdapter = new CarTroubleCanACAdapter(mContext, leftStr);
        mListView = (ListView) mViewRoot.findViewById(R.id.list_view);
        mListView.setAdapter(mCanACAdapter);
        initListener();
    }


    private void initListener() {

    }

    private void canDataCallBack(Message msg) {
        int id = msg.what;
        if (mCurrFragmentID == id) {
            mCarTroubleCanACInfos = (int[]) msg.obj;
            mCanACAdapter.setRightData(mCarTroubleCanACInfos);
        }
    }

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            canDataCallBack(msg);
        }
    };

具体的请下载demo源码分析之;那么使用方式如下:
CarTroubleActivity.java类实现:

package com.asir.viewpagerandfragment;

import com.asir.viewpagerandfragment.fragement.BaseFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanACFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanBMSFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanChargerFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanDCDCFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanESPFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleCanPMSMFragment;
import com.asir.viewpagerandfragment.fragement.CarTroubleVehicleFragment;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;

@SuppressLint("NewApi")
/**
 * 汽车故障
 * 
 * @author Administrator
 */
public class CarTroubleActivity extends Activity {
    private FragmentManager mFragmentManager;
    private RadioGroup mRadioGroupCenterItems;
    private RadioButton mRadioCartroubleItem0;
    private RadioButton mRadioCartroubleItem1;
    private RadioButton mRadioCartroubleItem2;
    private RadioButton mRadioCartroubleItem3;
    private RadioButton mRadioCartroubleItem4;
    private RadioButton mRadioCartroubleItem5;
    private RadioButton mRadioCartroubleItem6;
    public static final int mItemsPosition0 = 0;
    public static final int mItemsPosition1 = 1;
    public static final int mItemsPosition2 = 2;
    public static final int mItemsPosition3 = 3;
    public static final int mItemsPosition4 = 4;
    public static final int mItemsPosition5 = 5;
    public static final int mItemsPosition6 = 6;
    public static final int mItemsPosition0_Column = 4;
    public static final int mItemsPosition1_Column = 5;
    public static final int mItemsPosition2_Column = 6;
    public static final int mItemsPosition3_Column = 7;
    public static final int mItemsPosition4_Column = 8;
    public static final int mItemsPosition5_Column = 9;
    public static final int mItemsPosition6_Column = 10;
    private BaseFragment mCarTroubleVehicleFragment;
    private BaseFragment mCarTroubleCanBMSFragment;
    private BaseFragment mCarTroubleCanPMSMFragment;
    private BaseFragment mCarTroubleCanDCDCFragment;
    private BaseFragment mCarTroubleCanChargerFragment;
    private BaseFragment mCarTroubleCanESPFragment;
    private BaseFragment mCarTroubleCanACFragment;
    private final String mCarTroubleVehicleFragmentTAG = "item0_tag";
    private final String mCarTroubleCanBMSFragmentTAG = "item1_tag";
    private final String mCarTroubleCanPMSMFragmentTAG = "item2_tag";
    private final String mCarTroubleCanDCDCFragmentTAG = "item3_tag";
    private final String mCarTroubleCanChargerFragmentTAG = "item4_tag";
    private final String mCarTroubleCanESPFragmentTAG = "item5_tag";
    private final String mCarTroubleCanACFragmentTAG = "item6_tag";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.car_trouble);
        isSaveFragment(savedInstanceState);
        initView();
        initData();
        initListener();
    }

    /**
     * 解决Fragment界面重叠问题
     * 
     * @param savedInstanceState
     */
    private void isSaveFragment(Bundle savedInstanceState) {
        mFragmentManager = getFragmentManager();
        if (savedInstanceState != null) {
            mCarTroubleVehicleFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleVehicleFragmentTAG);
            mCarTroubleCanBMSFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanBMSFragmentTAG);
            mCarTroubleCanPMSMFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanPMSMFragmentTAG);
            mCarTroubleCanDCDCFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanDCDCFragmentTAG);
            mCarTroubleCanChargerFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanChargerFragmentTAG);
            mCarTroubleCanESPFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanESPFragmentTAG);
            mCarTroubleCanACFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanACFragmentTAG);
        }
    }
    @Override
    /**
     * 实现这个方法,并注释掉下面这行代码可以解决Fragment界面重叠问题
     */
    protected void onSaveInstanceState(Bundle outState) {
        // super.onSaveInstanceState(outState);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // System.gc();
    }

    private void initView() {
        mRadioGroupCenterItems = (RadioGroup) findViewById(R.id.rg_center_car_trouble_items);
        mRadioCartroubleItem0 = (RadioButton) findViewById(R.id.car_trouble_item0);
        mRadioCartroubleItem1 = (RadioButton) findViewById(R.id.car_trouble_item1);
        mRadioCartroubleItem2 = (RadioButton) findViewById(R.id.car_trouble_item2);
        mRadioCartroubleItem3 = (RadioButton) findViewById(R.id.car_trouble_item3);
        mRadioCartroubleItem4 = (RadioButton) findViewById(R.id.car_trouble_item4);
        mRadioCartroubleItem5 = (RadioButton) findViewById(R.id.car_trouble_item5);
        mRadioCartroubleItem6 = (RadioButton) findViewById(R.id.car_trouble_item6);
    }

    private void initData() {
        // 先初始化第一个item里面的 内容
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        if (mCarTroubleVehicleFragment == null) {
            mCarTroubleVehicleFragment = new CarTroubleVehicleFragment();
            transaction.add(R.id.content_view, mCarTroubleVehicleFragment);
        }
        transaction.commit();
    }

    private void initListener() {
        mRadioGroupCenterItems.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                FragmentTransaction transaction = mFragmentManager.beginTransaction();
                hideFragments(transaction);
                switch (checkedId) {
                case R.id.car_trouble_item0:
                    if (mCarTroubleVehicleFragment == null) {
                        mCarTroubleVehicleFragment = new CarTroubleVehicleFragment();
                        transaction.add(R.id.content_view, mCarTroubleVehicleFragment, mCarTroubleVehicleFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleVehicleFragment);
                    }
                    break;
                case R.id.car_trouble_item1:
                    if (mCarTroubleCanBMSFragment == null) {
                        mCarTroubleCanBMSFragment = new CarTroubleCanBMSFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanBMSFragment, mCarTroubleCanBMSFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanBMSFragment);
                    }
                    break;
                case R.id.car_trouble_item2:
                    if (mCarTroubleCanPMSMFragment == null) {
                        mCarTroubleCanPMSMFragment = new CarTroubleCanPMSMFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanPMSMFragment, mCarTroubleCanPMSMFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanPMSMFragment);
                    }
                    break;
                case R.id.car_trouble_item3:
                    if (mCarTroubleCanDCDCFragment == null) {
                        mCarTroubleCanDCDCFragment = new CarTroubleCanDCDCFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanDCDCFragment, mCarTroubleCanDCDCFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanDCDCFragment);
                    }
                    break;
                case R.id.car_trouble_item4:
                    if (mCarTroubleCanChargerFragment == null) {
                        mCarTroubleCanChargerFragment = new CarTroubleCanChargerFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanChargerFragment,
                                mCarTroubleCanChargerFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanChargerFragment);
                    }
                    break;
                case R.id.car_trouble_item5:
                    if (mCarTroubleCanESPFragment == null) {
                        mCarTroubleCanESPFragment = new CarTroubleCanESPFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanESPFragment, mCarTroubleCanESPFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanESPFragment);
                    }
                    break;
                case R.id.car_trouble_item6:
                    if (mCarTroubleCanACFragment == null) {
                        mCarTroubleCanACFragment = new CarTroubleCanACFragment();
                        transaction.add(R.id.content_view, mCarTroubleCanACFragment, mCarTroubleCanACFragmentTAG);
                    } else {
                        transaction.show(mCarTroubleCanACFragment);
                    }
                    break;
                }
                transaction.commit();
            }
        });
    }

    private void hideFragments(FragmentTransaction transaction) {
        if (mCarTroubleVehicleFragment != null)
            transaction.hide(mCarTroubleVehicleFragment);
        if (mCarTroubleCanBMSFragment != null)
            transaction.hide(mCarTroubleCanBMSFragment);
        if (mCarTroubleCanPMSMFragment != null)
            transaction.hide(mCarTroubleCanPMSMFragment);
        if (mCarTroubleCanDCDCFragment != null)
            transaction.hide(mCarTroubleCanDCDCFragment);
        if (mCarTroubleCanChargerFragment != null)
            transaction.hide(mCarTroubleCanChargerFragment);
        if (mCarTroubleCanESPFragment != null)
            transaction.hide(mCarTroubleCanESPFragment);
        if (mCarTroubleCanACFragment != null)
            transaction.hide(mCarTroubleCanACFragment);
    }

}

这边我们在使用fragment这种做法时,在切换界面时不要重复去加载界面,也不要去replayce重新加载,这种会很浪费资源,浪费时间;最好的做法就是将已经加载过的fragment再切换界面时将其隐藏,然后再使用fragment实现方式时会有这种问题出现,估计用得多人都有这个体会了,就是fragment的界面重叠问题,那么解决方法如下;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.car_trouble);
        isSaveFragment(savedInstanceState);
        initView();
        initData();
        initListener();
    }

    /**
     * 解决Fragment界面重叠问题
     * 
     * @param savedInstanceState
     */
    private void isSaveFragment(Bundle savedInstanceState) {
        mFragmentManager = getFragmentManager();
        if (savedInstanceState != null) {
            mCarTroubleVehicleFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleVehicleFragmentTAG);
            mCarTroubleCanBMSFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanBMSFragmentTAG);
            mCarTroubleCanPMSMFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanPMSMFragmentTAG);
            mCarTroubleCanDCDCFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanDCDCFragmentTAG);
            mCarTroubleCanChargerFragment = (BaseFragment) mFragmentManager
                    .findFragmentByTag(mCarTroubleCanChargerFragmentTAG);
            mCarTroubleCanESPFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanESPFragmentTAG);
            mCarTroubleCanACFragment = (BaseFragment) mFragmentManager.findFragmentByTag(mCarTroubleCanACFragmentTAG);
        }
    }
    @Override
    /**
     * 实现这个方法,并注释掉下面这行代码可以解决Fragment界面重叠问题
     */
    protected void onSaveInstanceState(Bundle outState) {
        // super.onSaveInstanceState(outState);
    }

方式二通过viewpager:
代码实现部分如下:
这里写图片描述
个人这个车辆信息应用为什么要采用这种方式去实现呢,因为viewpager比fragment实现方式显得更加轻量级一些,而且可以避免应用重启时的界面重叠的问题。选择加载一个fragment然后用viewpager显示多个页面。
BasePage.java代码如下:

package com.asir.viewpagerandfragment.pages;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;

public abstract class BasePage {
    protected Context mContext;
    protected View mViewRoot;

    /**
     * 1 。画界面 2 初始化数据
     */
    public BasePage(Context ct) {
        this.mContext = ct;

        LayoutInflater inflater = (LayoutInflater) ct.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mViewRoot = initView(inflater);
        initData();
    }

    public View getRootView() {
        return mViewRoot;
    }

    public abstract View initView(LayoutInflater inflater);

    public abstract void initData();
}

这边写一个抽象父类pagerBean类(这边Bean指的是一个对象封装),提供两个抽象方法initView(),一个initData(),再提供一各getRootView()返回当前加载的视图xml界面,然后让所有的子viewpagerBean类去继承这个Basepager类去实现两个抽象方法;然后在使用的时候用List队列添加子类pagerBean,在PagerAdapter加载时添加pagerBean之前加载的view视图即可,使用方式具体代码如下:
MyCarHomeFragment.java

package com.asir.viewpagerandfragment.fragement;

import java.util.ArrayList;  
import java.util.List;

import com.asir.viewpagerandfragment.R;
import com.asir.viewpagerandfragment.pages.BasePage;
import com.asir.viewpagerandfragment.pages.MyCarBatteryInfoPage;
import com.asir.viewpagerandfragment.pages.MyCarCarStatusPage;
import com.asir.viewpagerandfragment.pages.MyCarMonomerBatteryPage;
import com.asir.viewpagerandfragment.pages.MyCarMotorInfoPage;
import com.asir.viewpagerandfragment.view.MyCarViewPager;
import com.asir.viewpagerandfragment.view.MyCarViewPager.OnPageChangeListener;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class MyCarHomeFragment extends BaseFragment implements OnClickListener {
    private ViewGroup mViewRoot;
    private MyCarViewPager mViewPager;
    private RadioGroup mRadioGroupBottoms;
    private List<BasePage> mPageList = new ArrayList<BasePage>();
    private MyCarCarStatusPage mMyCarCarStatusPage;
    private MyCarBatteryInfoPage mMyCarBatteryInfoPage;
    private MyCarMotorInfoPage mMyCarMotorInfoPage;
    private MyCarMonomerBatteryPage mMyCarMonomerBatteryPage;

    @Override
    public View initView(LayoutInflater inflater) {
        mViewRoot = (ViewGroup) inflater.inflate(R.layout.my_car_home_fragment, null);
        mRadioGroupBottoms = (RadioGroup) mViewRoot.findViewById(R.id.main_radio);
        mViewPager = (MyCarViewPager) mViewRoot.findViewById(R.id.viewpager);
        initPagesView();
        return mViewRoot;
    }

    @Override
    public void initData(Bundle savedInstanceState) {

        initListener();
    }

    private void initListener() {
        int childCount = mRadioGroupBottoms.getChildCount();
        for (int i = 0; i < childCount; i++) {
            mRadioGroupBottoms.getChildAt(i).setOnClickListener(MyCarHomeFragment.this);
        }
        mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                RadioButton rb = (RadioButton) mRadioGroupBottoms.getChildAt(position);
                rb.setChecked(true);
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }

    private void initPagesView() {
        mMyCarCarStatusPage = new MyCarCarStatusPage(mContext);
        mMyCarBatteryInfoPage = new MyCarBatteryInfoPage(mContext);
        mMyCarMotorInfoPage = new MyCarMotorInfoPage(mContext);
        mMyCarMonomerBatteryPage = new MyCarMonomerBatteryPage(mContext);

        mPageList.add(mMyCarCarStatusPage);
        mPageList.add(mMyCarBatteryInfoPage);
        mPageList.add(mMyCarMotorInfoPage);
        mPageList.add(mMyCarMonomerBatteryPage);
        HomePageAdapter adapter = new HomePageAdapter(mContext, mPageList);
        mViewPager.setAdapter(adapter);
    }

    class HomePageAdapter extends PagerAdapter {
        private Context ct;
        private List<BasePage> list;

        public HomePageAdapter(Context ct, List<BasePage> list) {
            this.ct = ct;
            this.list = list;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // super.destroyItem(container, position, object);
            ((MyCarViewPager) container).removeView(list.get(position).getRootView());

        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((MyCarViewPager) container).addView(list.get(position).getRootView(), 0);
            return list.get(position).getRootView();
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.car_status:
            mViewPager.setCurrentItem(0, false);
            break;
        case R.id.battery_info:
            mViewPager.setCurrentItem(1, false);
            break;
        case R.id.motor_info:
            mViewPager.setCurrentItem(2, false);
            break;
        case R.id.monomer_battery:
            mViewPager.setCurrentItem(3, false);
            break;
        }
    }

}

有需要的朋友下载demo源码修改修改即可仿写微信,支付宝等大致布局样式,两种方式都可以实现,喜欢哪种就用哪种就好了。

源码点击下载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值