Android分栏控制器
陈世流年 人气:0近公司接了一个项目,需要会安卓,人手不够的情况作为一个开发iOS的也需要跟进,开始学习android,集成开发环境以后。直接就被难到了,iOS里面的分栏控制器(tabbarcontroller)android里面根本没有这个控件,安卓都是自己来实现这个效果的。所以开始研究android是如何实现的,下面这些代码。
当我们创建一个android APP项目的时候会自动生成一个MainActivity,我们可以在这Activity实现这个效果。首先我们先看一下效果图
代码实现
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/app_ui_bg" tools:context="com.zkteco.pridebiosecurity.view.MainActivity"> <FrameLayout android:id="@+id/main_fl" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <View android:layout_width="match_parent" android:layout_height="1px" android:background="@color/gray2"/> <LinearLayout android:layout_width="match_parent" android:layout_height="@dimen/d50" android:background="@color/white" android:orientation="horizontal"> <LinearLayout android:id="@+id/message_ll" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/message_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:scaleType="centerInside" android:src="@mipmap/ic_message_1"/> <TextView android:id="@+id/message_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d3" android:text="@string/message" android:textColor="@color/app_style_color" android:textSize="@dimen/s11"/> </LinearLayout> <LinearLayout android:id="@+id/clock_ll" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/clock_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:scaleType="centerInside" android:src="@mipmap/ic_clock_0"/> <TextView android:id="@+id/clock_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d3" android:text="@string/clock" android:textColor="@color/gray" android:textSize="@dimen/s11"/> </LinearLayout> <LinearLayout android:id="@+id/home_ll" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/home_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:scaleType="centerInside" android:src="@mipmap/ic_home_0"/> <TextView android:id="@+id/home_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d3" android:text="@string/home" android:textColor="@color/gray" android:textSize="@dimen/s11"/> </LinearLayout> <LinearLayout android:id="@+id/entrance_ll" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/entrance_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:scaleType="centerInside" android:src="@mipmap/ic_entrance_0"/> <TextView android:id="@+id/entrance_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d3" android:text="@string/entrance" android:textColor="@color/gray" android:textSize="@dimen/s11"/> </LinearLayout> <LinearLayout android:id="@+id/me_ll" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/me_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:scaleType="centerInside" android:src="@mipmap/ic_me_0"/> <TextView android:id="@+id/me_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d3" android:text="@string/me" android:textColor="@color/gray" android:textSize="@dimen/s11"/> </LinearLayout> </LinearLayout> </LinearLayout>
这样页面我们就实现了。
接下来就是点击切换页面的效果实现了,代码主要就是实现点击切换页面的功能。所以我们要关联一下五个Fragment了
package com.zkteco.pridebiosecurity.view; import android.annotation.SuppressLint; import android.os.Build; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.zkteco.pridebiosecurity.R; import com.zkteco.pridebiosecurity.base.BaseActivity; import com.zkteco.pridebiosecurity.base.BaseFragment; import com.zkteco.pridebiosecurity.util.StatusBarUtil; import com.zkteco.pridebiosecurity.view.clock.ClockFragment; import com.zkteco.pridebiosecurity.view.entrance.EntranceFragment; import com.zkteco.pridebiosecurity.view.home.HomeFragment; import com.zkteco.pridebiosecurity.view.me.MeFragment; import com.zkteco.pridebiosecurity.view.message.MessageFragment; import com.zkteco.pridebiosecurity.widget.TitleBar; /** * 程序主界面 * * Created by sunyd on 2019/2/22. */ public class MainActivity extends BaseActivity implements OnClickListener { private LinearLayout mMessageLl, mColckLl, mHomeLl, mEntranceLl, mMeLl; private ImageView mMessageIv, mColckIv, mHomeIv, mEntranceIv, mMeIv; private TextView mMessageTv, mColckTv, mHomeTv, mEntranceTv, mMeTv; private BaseFragment baseFragment; @Override protected int bindLayout() { return R.layout.activity_main; } @Override protected void initView() { // 设置状态栏背景蓝色,文字白色 StatusBarUtil.setStatusBarLightMode(this, false); mMessageLl = bindView(R.id.message_ll); mColckLl = bindView(R.id.clock_ll); mHomeLl = bindView(R.id.home_ll); mEntranceLl = bindView(R.id.entrance_ll); mMeLl = bindView(R.id.me_ll); mMessageIv = bindView(R.id.message_iv); mColckIv = bindView(R.id.clock_iv); mHomeIv = bindView(R.id.home_iv); mEntranceIv = bindView(R.id.entrance_iv); mMeIv = bindView(R.id.me_iv); mMessageTv = bindView(R.id.message_tv); mColckTv = bindView(R.id.clock_tv); mHomeTv = bindView(R.id.home_tv); mEntranceTv = bindView(R.id.entrance_tv); mMeTv = bindView(R.id.me_tv); changeFragment(MessageFragment.class, 0); } @Override protected void initData() { } @Override protected void setListeners() { mMessageLl.setOnClickListener(this); mColckLl.setOnClickListener(this); mHomeLl.setOnClickListener(this); mEntranceLl.setOnClickListener(this); mMeLl.setOnClickListener(this); } @Override protected void autoRefresh() { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.message_ll: changeFragment(MessageFragment.class, 0); break; case R.id.clock_ll: changeFragment(ClockFragment.class, 1); break; case R.id.home_ll: changeFragment(HomeFragment.class, 2); break; case R.id.entrance_ll: changeFragment(EntranceFragment.class, 3); break; case R.id.me_ll: changeFragment(MeFragment.class, 4); break; } } /** * 切换主界面 * @param clazz * @param position */ public void changeFragment(Class<? extends Fragment> clazz, int position) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); Fragment fragment = fm.findFragmentByTag(clazz.getName()); if (fragment == null) { try { fragment = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } } if (baseFragment != null && baseFragment != fragment) { ft.hide(baseFragment); } if (!fragment.isAdded()) { ft.add(R.id.main_fl, fragment, clazz.getName()); } else { ft.show(fragment); } ft.commitAllowingStateLoss(); baseFragment = (BaseFragment) fragment; mMessageIv.setImageResource(R.mipmap.ic_message_0); mColckIv.setImageResource(R.mipmap.ic_clock_0); mHomeIv.setImageResource(R.mipmap.ic_home_0); mEntranceIv.setImageResource(R.mipmap.ic_entrance_0); mMeIv.setImageResource(R.mipmap.ic_me_0); mMessageTv.setTextColor(getResources().getColor(R.color.gray)); mColckTv.setTextColor(getResources().getColor(R.color.gray)); mHomeTv.setTextColor(getResources().getColor(R.color.gray)); mEntranceTv.setTextColor(getResources().getColor(R.color.gray)); mMeTv.setTextColor(getResources().getColor(R.color.gray)); if (position == 0) { mMessageIv.setImageResource(R.mipmap.ic_message_1); mMessageTv.setTextColor(getResources().getColor(R.color.app_style_color)); } else if (position == 1) { mColckIv.setImageResource(R.mipmap.ic_clock_1); mColckTv.setTextColor(getResources().getColor(R.color.app_style_color)); } else if (position == 2) { mHomeIv.setImageResource(R.mipmap.ic_home_1); mHomeTv.setTextColor(getResources().getColor(R.color.app_style_color)); } else if (position == 3) { mEntranceIv.setImageResource(R.mipmap.ic_entrance_1); mEntranceTv.setTextColor(getResources().getColor(R.color.app_style_color)); } else if (position == 4) { mMeIv.setImageResource(R.mipmap.ic_me_1); mMeTv.setTextColor(getResources().getColor(R.color.app_style_color)); } } }
这里呢,每一个Fragment都继承了BaseFragment,下面是BaseFragment的代码实现
/** * TODO * By sunyd, 2016-7-19 */ package com.zkteco.pridebiosecurity.base; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.FragmentManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zkteco.pridebiosecurity.widget.LoadingDialog; /** * fragment基类 * * @author sunyd, 2016-7-19 */ public abstract class BaseFragment extends android.support.v4.app.Fragment { protected Context mContext; private LoadingDialog mABLoadingDialog; protected View mRootView; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override @Nullable public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(bindLayout(), container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mABLoadingDialog = new LoadingDialog(getActivity()); mContext = getActivity(); mRootView = view; initView(); } protected <T extends View> T bindView(int id) { @SuppressWarnings("unchecked") T t = (T) mRootView.findViewById(id); return t; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initData(); setListeners(); } @Override public void onResume() { super.onResume(); autoRefresh(); } /** * 绑定布局 * @return */ protected abstract int bindLayout(); /** * 初始化组件 */ protected abstract void initView(); /** * 数据 */ protected abstract void initData(); /** * 设置监听 */ protected abstract void setListeners(); /** * 自动刷新 */ protected abstract void autoRefresh(); /** * 加载动画 * @param show */ public void showOrHideWaitBar(boolean show) { if (mABLoadingDialog != null) { if (show) { mABLoadingDialog.show(); } else { mABLoadingDialog.dismiss(); } } } @Override public void onDestroy() { if (mABLoadingDialog != null && mABLoadingDialog.isDialogShowing()) { mABLoadingDialog.dismiss(); } super.onDestroy(); } }
MainActivity继承BaseActivity,下面便是BaseActivity实现代码
package com.zkteco.pridebiosecurity.base; import android.annotation.SuppressLint; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.Window; import android.view.WindowManager; import com.zkteco.pridebiosecurity.R; import com.zkteco.pridebiosecurity.util.StatusBarUtil; import com.zkteco.pridebiosecurity.widget.LoadingDialog; /** * activity基类 * * @author sunyd, 2019-2-25 */ @SuppressLint("NewApi") public abstract class BaseActivity extends AppCompatActivity { private LoadingDialog mABLoadingDialog; protected Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); BaseApplication.getInstance().addActivity(this); // 设置状态栏背景白色,文字黑色 StatusBarUtil.setStatusBarLightMode(this, true); setContentView(bindLayout()); mABLoadingDialog = new LoadingDialog(this); mContext = this; initView(); initData(); setListeners(); } @Override protected void onResume() { super.onResume(); autoRefresh(); } @Override public void finish() { BaseApplication.getInstance().removeAcitivity(this); super.finish(); } /** * 简化初始化过程 * @param id * @param <T> * @return */ protected <T extends View> T bindView(int id) { @SuppressWarnings("unchecked") T t = (T) findViewById(id); return t; } /** * 绑定布局 * @return */ protected abstract int bindLayout(); /** * 初始化组件 */ protected abstract void initView(); /** * 数据 */ protected abstract void initData(); /** * 设置监听 */ protected abstract void setListeners(); /** * 自动刷新 */ protected abstract void autoRefresh(); /** * 加载动画 */ public void showOrHideWaitBar(boolean show) { if (mABLoadingDialog != null) { if (show) { mABLoadingDialog.show(); } else { mABLoadingDialog.dismiss(); } } } @Override public void onDestroy() { if (mABLoadingDialog != null && mABLoadingDialog.isDialogShowing()) { mABLoadingDialog.dismiss(); } super.onDestroy(); } }
以上便实现了,这个功能的所有效果。
当我们APP使用时也会常用到Application,也就是iOS里面的AppDelegate。可以方便我们实现很多方法
下面是Application的实现
package com.zkteco.pridebiosecurity.base; import android.app.Activity; import android.app.Application; import android.content.Intent; import com.zkteco.pridebiosecurity.util.CrashHandler; import com.zkteco.pridebiosecurity.view.login.LoginActivity; import java.util.Set; import java.util.WeakHashMap; /** * APP主入口 * * @author sunyd, 2016-7-19 */ public class BaseApplication extends Application { private final WeakHashMap<Activity, Integer> mActivityGroup = new WeakHashMap<>(1); private static BaseApplication sInstance = null; @Override public void onCreate() { super.onCreate(); sInstance = this; } /** * 获取全局context * @return */ public static BaseApplication getInstance() { return sInstance; } /** * 添加Activity * @param a */ protected void addActivity(Activity a) { mActivityGroup.put(a, 0); } /** * 移除Activity * @param a */ protected void removeAcitivity(Activity a) { mActivityGroup.remove(a); } /** * 获取所有Activity * @param c * @return */ public Activity getActivityOfClass(Class<?> c) { Set<Activity> set = mActivityGroup.keySet(); for (Activity a : set) { if (a.getClass() == c) { return a; } } return null; } /** * 退出所有Activity */ public void exitAllActivities() { while (mActivityGroup.size() > 0) { Set<Activity> as = mActivityGroup.keySet(); ((Activity[]) as.toArray())[0].finish(); } mActivityGroup.clear(); } }
加载全部内容