您的位置:首页 > 其它

从框架到完整项目搭建,实战项目《约个球》(6)- 利用SlidingMenu和Fragment构建我们的项目结构

2016-01-25 10:34 686 查看
项目github地址:https://github.com/CameloeAnthony/DatingBall



step1

关于SlidingMenu的基础用法,参考这边文章 /article/1345563.html



既然我们的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();
}
}


可以看到我是让自己的MainActivity继承了AbsMainActivity,接下来看看一它里面的代码。

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;
}
}


这里面我们就初始化了SlidingMenu,而且把MainFragment,LeftFragment和RightFragment的实现进行了抽象。所以以后每次我们自己的的MainActivity只需要继承上面这个类实现里面的方法就是咯。

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中去。

于是我们自己的MainFragment就简化了许多。

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的初步搭建。后面的文章将继续分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: