本文主要是介绍仿微信主页布局,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
先来看看微信整体布局方式及市面上一些常见的应用大致布局方式,几乎都是采用顶部或者底部一个菜单栏控制方式,然后中间一些内容显示界面,下面是微信应用、腾讯新闻和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;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {mViewRoot = initView(inflater);return mViewRoot;}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);initData(savedInstanceState);}@Overridepublic 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;@Overridepublic View initView(LayoutInflater inflater) {return (View) inflater.inflate(R.layout.list_view, null);}@Overridepublic 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";@Overrideprotected 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);}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);}@Overrideprotected void onStart() {super.onStart();}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onPause() {super.onPause();}@Overrideprotected void onStop() {super.onStop();}@Overrideprotected 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() {@Overridepublic 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的界面重叠问题,那么解决方法如下;
@Overrideprotected 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;@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void onPageSelected(int position) {RadioButton rb = (RadioButton) mRadioGroupBottoms.getChildAt(position);rb.setChecked(true);}@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic 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;}@Overridepublic int getCount() {return list.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// super.destroyItem(container, position, object);((MyCarViewPager) container).removeView(list.get(position).getRootView());}@Overridepublic Object instantiateItem(ViewGroup container, int position) {((MyCarViewPager) container).addView(list.get(position).getRootView(), 0);return list.get(position).getRootView();}}@Overridepublic 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源码修改修改即可仿写微信,支付宝等大致布局样式,两种方式都可以实现,喜欢哪种就用哪种就好了。
源码点击下载
这篇关于仿微信主页布局的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!