项目github地址:https://github.com/CameloeAnthony/DatingBall
step1
关于SlidingMenu的基础用法,参考这边文章 http://blog.csdn.net/lmj623565791/article/details/36677279
既然我们的SlidingMenu会出现在我们以后大多数的项目中,我们为何不采用SlidingMenu来构建我们的项目的 公共部分,而我们不用每次都去初始化配置SlidingMenu了。以后我们写自己的MainActivity就只用像下面这样写了,是不是简单了许多。
package com.nsu.datingball.activity; import android.os.Bundle; import android.support.v4.app.Fragment; import com.nsu.datingball.fragment.LeftFragment; import com.nsu.datingball.fragment.MainFragment; import com.nsu.datingball.fragment.RightFragment; import com.nsu.library.app.AbsMainActivity; /** * Create By Anthony on 2016/1/119 * 当前类注释:实现了AbsMainActivity,添加MainFragment,LeftFragment和RightFragment */ public class MainActivity extends AbsMainActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected Fragment getMainFragment() { return new MainFragment(); } @Override protected Fragment getLeftFragment() { return new LeftFragment(); } @Override protected Fragment getRightFragment() { return new RightFragment(); } }
package com.nsu.library.app; import android.os.Bundle; import android.support.v4.app.Fragment; import android.widget.Toast; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.nsu.library.R; /** * Create By Anthony on 2016/1/119 * 当前类注释:实现了左右slidingmenu的activity,以及返回键处理 */ public abstract class AbsMainActivity extends AbsFragmentActivity { private SlidingMenu mSlidingMenu; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.abs_activity_main); initSlidingMenu(); } private void initSlidingMenu() { // 设置滑动菜单的属性值 mSlidingMenu = new SlidingMenu(this); mSlidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT); mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN); // mSlidingMenu.setFadeDegree(0.35f); // 设置主界面视图 getSupportFragmentManager().beginTransaction() .replace(R.id.main_frame, getMainFragment()).commit(); //设置左侧菜单 mSlidingMenu.setShadowDrawable(R.drawable.shadow_left_menu); mSlidingMenu.setShadowWidthRes(R.dimen.custom_shadow_left_menu_width); mSlidingMenu.setBehindWidthRes(R.dimen.left_menu_width); mSlidingMenu.setMenu(R.layout.frame_left_menu); getSupportFragmentManager().beginTransaction() .replace(R.id.leftMenu, getLeftFragment()).commit(); //设置右侧菜单 mSlidingMenu.setSecondaryShadowDrawable(R.drawable.shadow_right_menu); mSlidingMenu.setShadowWidthRes(R.dimen.custom_shadow_right_menu_width); mSlidingMenu.setSecondaryBehindWidthRes(R.dimen.right_menu_width); mSlidingMenu.setSecondaryMenu(R.layout.frame_right_menu); getSupportFragmentManager().beginTransaction() .replace(R.id.rightMenu, getRightFragment()).commit(); } private long lastBackKeyDownTick = 0; public static final long MAX_DOUBLE_BACK_DURATION = 1500; @Override public void onBackPressed() { if(mSlidingMenu.isMenuShowing() || mSlidingMenu.isSecondaryMenuShowing()) { mSlidingMenu.toggle(true); return; } long currentTick = System.currentTimeMillis(); if (currentTick - lastBackKeyDownTick > MAX_DOUBLE_BACK_DURATION) { Toast.makeText(this, R.string.exit_app_tips, Toast.LENGTH_SHORT).show(); lastBackKeyDownTick = currentTick; } else { super.onBackPressed(); } } /** Implement these functions to return your fragment */ abstract protected Fragment getMainFragment(); abstract protected Fragment getLeftFragment(); abstract protected Fragment getRightFragment(); /** Getter and Setter */ public SlidingMenu getSlidingMenu() { return mSlidingMenu; } }
abs_activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_frame" android:background="#ffffff" android:layout_width="match_parent" android:layout_height="match_parent" />
frame_left_menu.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/leftMenu" android:layout_width="match_parent" android:layout_height="match_parent" />frame_right_menu.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rightMenu" android:layout_width="match_parent" android:layout_height="match_parent" />
step2
对于我们MainFragment呢,大多数时候我们看到的项目都是下面的结构。
所以我们的MainFragment也可以进行一定程度的抽象,让子类明确自己需要实现哪一些方法。下面是父类
package com.nsu.library.fragment; import android.content.Context; import android.content.res.ColorStateList; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.nsu.library.R; /** * Create By Anthony on 2016/1/21 * 当前类注释:抽象的四个tab和四个fragment组成的通用MainFragment */ public abstract class AbsMainFragment extends AbsFragment implements View.OnClickListener { private Context mContext; private FragmentManager mFragmentManager; private int tabCount = 5; private static final int INIT_TAB_INDEX = 0; private int mCurrentIndex = -1; private LinearLayout mBottomLayout; private LinearLayout mTopLayout; private String[] tabTexts; private int[] tabImgIds; private FragmentTransaction transaction; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); mContext = getActivity(); View v = inflater.inflate(getViewID(), container, false); mFragmentManager = getChildFragmentManager(); initViews(v); initTabs(); return v; } /** * 获取顶部和底部的布局,子类需要实现 getTabTexts();getTabImgs();来返回底部tab的文字和图片 * 请确保 getTabTexts();getTabImgs();获取到的图片和文字数量与tabcount一致 */ private void initViews(View v) { mBottomLayout = (LinearLayout) v.findViewById(R.id.bottomId); mTopLayout = (LinearLayout) v.findViewById(R.id.topId); tabTexts = getTabTexts(); tabImgIds = getTabImgIds(); if (tabTexts.length != tabImgIds.length || tabTexts.length != tabCount || tabImgIds.length != tabCount) { throw new IllegalArgumentException ("make sure the number of your tab count , tab texts and tab imgs are the same "); } } /** * 初始化底部tabs */ private void initTabs() { for (int i = 0; i < tabCount; i++) { //设置底部tab布局,由一个图标和下方文字组成 LayoutInflater inflater = LayoutInflater.from(mContext); View btn = inflater.inflate(R.layout.btn_tab, null); btn.setClickable(true); btn.setTag(i); //设置底部tab名称 TextView tx = (TextView) btn.findViewById(R.id.btn_tab_text); tx.setText(tabTexts[i]); //设置按钮文字颜色 ColorStateList csl = mContext.getResources().getColorStateList(R.color.btn_tab_text_color); if (csl != null) { tx.setTextColor(csl); } //获取tab的图片 ImageView icon = (ImageView) btn.findViewById(R.id.btn_tab_img); icon.setImageDrawable(getResources().getDrawable(tabImgIds[i])); //设置点击事件 btn.setOnClickListener(this); //加入底部BottomLayout中 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1); mBottomLayout.addView(btn, params); //选中第一个tab if (!(mCurrentIndex == INIT_TAB_INDEX)) { mCurrentIndex = INIT_TAB_INDEX; setTabSelection(mCurrentIndex); switchContent(mCurrentIndex); } } } /** * 定义整个MainFragmentde layout id; * required id: * R.id.bottomId 底部layout * R.id.topId 顶部layout * R.id.tabContent 中间内容layout */ protected int getViewID() { return R.layout.fragment_main; } @Override public void onClick(View view) { int index = (Integer) view.getTag(); if (!(mCurrentIndex == index)) { mCurrentIndex = index; setTabSelection(mCurrentIndex); switchContent(mCurrentIndex); } } private void switchContent(int index) { //1 获得FragmentTrasaction对象 transaction = mFragmentManager.beginTransaction(); Fragment childFragment = null; if (mFragmentManager.findFragmentByTag(String.valueOf(index)) == null) { //2 通过配置初始化一个fragment. switch (index) { case 0: childFragment = Fragment.instantiate(mContext, Tab1Fragment().getClass().getName()); break; case 1: childFragment = Fragment.instantiate(mContext, Tab2Fragment().getClass().getName()); break; case 2: childFragment = Fragment.instantiate(mContext, Tab3Fragment().getClass().getName()); break; case 3: childFragment = Fragment.instantiate(mContext, Tab4Fragment().getClass().getName()); break; case 4: childFragment = Fragment.instantiate(mContext, Tab5Fragment().getClass().getName()); break; } } //3 给fragment赋值.通过title 和url实现fragment的参数的从父Fragment传递到子fragment // Bundle bundle = childFragment.getArguments(); // bundle = bundle == null ? new Bundle() : bundle; // bundle.putString(AbsFragment.EXTRA_TITLE, getTitle()); // bundle.putString(AbsFragment.EXTRA_URL, getUrl()); // childFragment.setArguments(bundle); //4 替换掉当前的container transaction.replace(R.id.containerId, childFragment, String.valueOf(index)); transaction.commit(); } private void setTabSelection(int tag) { clearSelectedState(); View childView = mBottomLayout.findViewWithTag(tag); childView.setSelected(true); } private void clearSelectedState() { for (int i = 0; i < mBottomLayout.getChildCount(); i++) { View childView = mBottomLayout.getChildAt(i); childView.setSelected(false); } } public int getCurrentIndex() { return mCurrentIndex; } protected abstract String[] getTabTexts(); protected abstract int[] getTabImgIds(); // protected abstract int getColorId(); protected abstract Fragment Tab1Fragment(); protected abstract Fragment Tab2Fragment(); protected abstract Fragment Tab3Fragment(); protected abstract Fragment Tab4Fragment(); protected abstract Fragment Tab5Fragment(); public LinearLayout getTopLayout() { return mTopLayout; } // protected abstract void switchContent(int index);//根据当前下标切换MainFragmenty的子fragment }上面的父类将添加到library中去。
package com.nsu.datingball.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.view.View; import com.nsu.datingball.R; import com.nsu.library.fragment.AbsMainFragment; /** * Create By Anthony on 2016/1/21 * 当前类注释:MainFragment的实现 */ public class MainFragment extends AbsMainFragment { String[] stringNames; int[] drawableIds; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } // @Override // protected int getColorId() { // return com.nsu.library.R.color.btn_tab_text_color; // } @Override protected String[] getTabTexts() { stringNames=getResources().getStringArray(R.array.list_tab_items); return stringNames; } @Override protected int[] getTabImgIds() { drawableIds=new int[]{R.drawable.selector_btn_tab_1,R.drawable.selector_btn_tab_2, R.drawable.selector_btn_tab_3,R.drawable.selector_btn_tab_4,R.drawable.selector_btn_tab_5}; return drawableIds; } @Override protected Fragment Tab1Fragment() { return new Tab1Fragment(); } @Override protected Fragment Tab2Fragment() { return new Tab2Fragment(); } @Override protected Fragment Tab3Fragment() { return new Tab3Fragment(); } @Override protected Fragment Tab4Fragment() { return new Tab4Fragment(); } @Override protected Fragment Tab5Fragment() { return new Tab5Fragment(); } }这也就完成了我们MainActivity的初步搭建。后面的文章将继续分析