一款安卓应用,好歹也是一个系统啊,既然称得上是系统,就要考虑系统的稳定性,功能模块的耦合性,复用程度等等,所以一个好的开发模型必然达到事半功倍的效果。
目前(2015年11月),常见的手机应用基本上是登录之后是一个主页,首页里面嵌套着多个fragment或者view,fragment会采用缓存策略,点击里面的控件,例如按钮,图片,会弹出一个新的activity,负责给用户提供特定的服务。最为关键的是主页,主页显示的内容通常是比较全面的,数据很多,例如微信的主页,下面是4个tab(微信,通讯录,发现,我),每点击一个tab,tab上面内容都会切换到对应的Fragment或者view里面。无论它们怎么切换,都在同一个activity里面,这个activity就是主activity,我习惯的命名是MainAcitivity。除了MainActivity,其他新建的Activity,一般用户要求是有统一标题栏风格,这个时候就要考虑写一个activity的基类BaseActivity。然后所有的Activity都是这个基类的子类,如果后期需要修改风格(比如切换皮肤什么的)只要修改基类就可以了。
BaseActivity基类,负责处理窗口切换的动画效果,手势,图片资源回收等,是对activity的第一层封装
package com.example.activitymode;
import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
/**
* 基础Activity
* 处理窗口切换动画,手势,回收图片资源等
*
*/
public class BaseActivity extends FragmentActivity {
final int RIGHT = 0;
final int LEFT = 1;
protected GestureDetector gestureDetector;
protected RelativeLayout mChildContent;
/**
* 是否执行界面切换动画
*/
protected boolean isAnimation = true;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 设置切换窗口的模式
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
gestureDetector = new GestureDetector(this, onGestureListener);
}
@Override
public void setContentView(int layoutResID) {
// TODO Auto-generated method stub
super.setContentView(R.layout.base_layout);
mChildContent = (RelativeLayout) findViewById(R.id.main_content);
View childView = LayoutInflater.from(this).inflate(layoutResID,
mChildContent);
}
/**
* 开启窗口的动画模式,左右切换
*/
@Override
public void startActivity(Intent intent) {
// TODO Auto-generated method stub
super.startActivity(intent);
if (isAnimation) {
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
}
/**
* 跳转到新窗口时,根据结果实现回退
*/
@Override
public void startActivityForResult(Intent intent, int requestCode) {
// TODO Auto-generated method stub
super.startActivityForResult(intent, requestCode);
if (isAnimation) {
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
}
@Override
public void finish() {
// TODO Auto-generated method stub
super.finish();
if (isAnimation) {
overridePendingTransition(R.anim.push_right_in,
R.anim.push_right_out);
}
}
private GestureDetector.OnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (e2 == null || e1 == null) {
return false;
}
if (e2.getX() - e1.getX() > 20 && Math.abs(velocityX) > 0) {
} else if (e1.getX() - e2.getX() > 20 && Math.abs(velocityX) > 0) {
} else
return false;
return true;
}
};
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
/** 顶部功能菜单被点击,子类实现此方法处理点击的具体操作 */
public void topOpermenuClicked() {
}
@Override
protected void onPause() {
super.onPause();
if (baseReceiver != null)
unregisterReceiver(baseReceiver);
}
// 动态注册的广播接收器,当有接收到广播的时候,可以根据广播的action进行相应的操作
// 子类也可以绑定自己的动态广播接收器
protected BaseReceiver baseReceiver;
@Override
protected void onResume() {
super.onResume();
if (baseReceiver == null)
baseReceiver = new BaseReceiver();
IntentFilter filter = new IntentFilter(baseReceiver.ACTION);
registerReceiver(baseReceiver, filter);
}
// Activity销毁
@Override
protected void onDestroy() {
super.onDestroy();
}
/**
* 回收View
*
* @param v
*/
public void destroyLevelListView(View v) {
if (v == null)
return;
Drawable lld = v.getBackground();
if (lld == null)
return;
lld.setCallback(null);
lld = null;
v = null;
}
/**
* 回收图片
*
* @param v
* @param recycle
*/
public void destroyBackground(View v, boolean recycle) {
if (v == null)
return;
BitmapDrawable bd = (BitmapDrawable) v.getBackground();
if (bd == null)
return;
bd.setCallback(null);
if (recycle)
bd.getBitmap().recycle();
bd = null;
v = null;
}
/**
* 回收图片
*
* @param v
* @param recycle
*/
public void destroyDrawable(BitmapDrawable bd, boolean recycle) {
if (bd == null)
return;
bd.setCallback(null);
if (recycle)
bd.getBitmap().recycle();
bd = null;
}
/**
* 回收图片
*
* @param v
* @param recycle
*/
public void destroyDrawable(Drawable bd) {
if (bd == null)
return;
bd.setCallback(null);
bd = null;
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
public void destroyViews(View views[]) {
if (views == null || views.length == 0)
return;
for (View view : views) {
destroyViews(view, false);
}
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
public void destroyViews(View rootView, boolean recycle) {
if (rootView == null)
return;
ArrayList<View> views = rootView.getTouchables();
if (views != null && !views.isEmpty()) {
for (View view : views)
destroyView(view, recycle);
}
destroyView(rootView, recycle);
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
public void destroyViews(View rootView) {
if (rootView == null)
return;
ArrayList<View> views = rootView.getTouchables();
if (views != null && !views.isEmpty()) {
for (View view : views)
destroyView(view);
}
destroyView(rootView);
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
public void destroyView(View view) {
if (view == null)
return;
Drawable bd = view.getBackground();
destroyDrawable(bd);
view = null;
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
public void destroyView(View view, boolean recycle) {
if (view == null)
return;
Drawable bd = view.getBackground();
if (recycle)
destroyBackground(bd);
else
destroyDrawable(bd);
view = null;
}
/**
* 回收界面控件
*
* @param v
* @param recycle
*/
private void destroyBackground(Drawable bd) {
if (bd == null) {
return;
}
if (bd instanceof BitmapDrawable)
destroyDrawable((BitmapDrawable) bd, true);
else
destroyDrawable(bd);
bd = null;
}
}
BaseActivity的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/main_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
</RelativeLayout>
</LinearLayout>
通用窗口类CommoneActivity,继承于BaseActivity,集中处理统一的标题栏,非首页的Acititvy都应该继承它,
如本例中的MoreActivity
package com.example.activitymode;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 集中处理标题
* @author cgx
*
*/
public class CommonActivity extends BaseActivity {
protected LinearLayout llhead, llBack, llMenu;
protected RelativeLayout rlcontent, rlRoot;
protected TextView tvback, tvtitle, tvmenu;
/**
* 是否覆盖头部,默认不覆盖
*/
protected boolean isOverridehead = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
public void setContentView(int layoutResID, boolean isOverridehead) {
this.isOverridehead = isOverridehead;
this.setContentView(layoutResID);
}
@Override
public void setContentView(int layoutResID) {
// TODO Auto-generated method stub
super.setContentView(R.layout.common_activity_base_layout);
rlRoot = (RelativeLayout) findViewById(R.id.child_main);
llhead = (LinearLayout) findViewById(R.id.child_head);
rlcontent = (RelativeLayout) findViewById(R.id.chid_content);
tvback = (TextView) findViewById(R.id.child_back_text);
llBack = (LinearLayout) findViewById(R.id.child_back_layout);
tvtitle = (TextView) findViewById(R.id.child_title_text);
tvmenu = (TextView) findViewById(R.id.child_menu_text);
llMenu = (LinearLayout) findViewById(R.id.child_menu_layout);
if (!isOverridehead) {
View chidview = LayoutInflater.from(this).inflate(layoutResID,
rlcontent);
} else {
View chidview = LayoutInflater.from(this)
.inflate(layoutResID, null);
rlRoot.addView(chidview, 0);
llhead.setBackgroundResource(Color.parseColor("#00000000"));
}
llBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
setMenuVisibility(View.INVISIBLE);
}
public void setHeadVisibility(int visible) {
llhead.setVisibility(visible);
}
public void setTitle(String title) {
tvtitle.setText(title);
}
public void setMenuVisibility(int visible) {
llMenu.setVisibility(visible);
}
@Override
public void setTitle(CharSequence title) {
// TODO Auto-generated method stub
setTitle(title.toString());
}
public void setMenuText(String text) {
this.tvmenu.setText(text);
}
public void setMenuBK(int id) {
this.tvmenu.setBackgroundResource(id);
}
public void setOnMenuClickListen(OnClickListener onclicklistener) {
this.llMenu.setOnClickListener(onclicklistener);
}
@Override
public void setTitle(int titleId) {
// TODO Auto-generated method stub
setTitle(getText(titleId).toString());
}
}
通用窗口类CommonActivity的布局文件,新建窗口需要继承于它
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/child_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/child_head"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#654321"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/child_back_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp" >
<TextView
android:id="@+id/child_back_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/comeback"
android:gravity="center"
android:text=""
android:textColor="#ffffff"
android:textSize="14dp" />
</LinearLayout>
<TextView
android:id="@+id/child_title_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="标题"
android:textColor="#ffffff"
android:textSize="17dp" />
<LinearLayout
android:id="@+id/child_menu_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp" >
<TextView
android:id="@+id/child_menu_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/main_more_icon"
android:gravity="center"
android:text=""
android:textColor="#ffffff"
android:textSize="14dp" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/chid_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/child_head" />
</RelativeLayout>
首页MainActivity,内嵌了四个fragment,MainActivity直接继承于BaseActivity,制定属于首页的标题栏(导航栏)
package com.example.activitymode;
import java.util.ArrayList;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity";
private ViewPager vpContent;
private MainFragmentAdapter mFragmentAdapter;
private CommonFragmentSaveStatePagerAdapter myFragmentSaveStatePagerAdapter;
private ArrayList<CommonFragment> mFragments;
private ArrayList<String> mTitles;
Context mContext;
TextView tv1, tv2, tv3, tv4, tvmenu;
LinearLayout llMenu;
MyFragment1 mFragment1;
MyFragment2 mFragment2;
MyFragment3 mFragment3;
MyFragment4 mFragment4;
// ImageView ivCursor;
/**
* 主页四个page “第一个”page
*/
public static final int FIRST_PAGE = 0;
/**
* “第二个”page
*/
public static final int SECOND_PAGE = 1;
/**
* “第三个”page
*/
public static final int THIRD_PAGE = 2;
/**
* "第四个"page
*/
public static final int FOURTH_PAGE = 3;
private boolean isRegisterBroadcast = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main_layout);
initView();
initPageView();
initEvent();
initApp();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
private void initView() {
vpContent = (ViewPager) findViewById(R.id.v50_main_viewpager);
tv1 = (TextView) findViewById(R.id.main_text1);
tv1.setTextColor(Color.parseColor("#FFFF00"));
tv2 = (TextView) findViewById(R.id.main_text2);
tv3 = (TextView) findViewById(R.id.main_text3);
tv4 = (TextView) findViewById(R.id.main_text4);
tvmenu = (TextView) findViewById(R.id.main_menu_text);
llMenu = (LinearLayout) findViewById(R.id.main_menu_layout);
}
private void initEvent() {
// TODO Auto-generated method stub
tv1.setOnClickListener(mClickListener);
tv2.setOnClickListener(mClickListener);
tv3.setOnClickListener(mClickListener);
tv4.setOnClickListener(mClickListener);
llMenu.setOnClickListener(mClickListener);
vpContent.setOnPageChangeListener(mPageChangeListener);
}
private OnClickListener mClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_text1:// 第一个page
setCurPage(FIRST_PAGE);
break;
case R.id.main_text2:// 第二个page
setCurPage(SECOND_PAGE);
break;
case R.id.main_text3:// 第三个page
setCurPage(THIRD_PAGE);
break;
case R.id.main_text4:// 第四个page
setCurPage(FOURTH_PAGE);
break;
case R.id.main_menu_layout:// 菜单
IntentToMoreActivity();
break;
default:
break;
}
}
};
public void setCurPage(int page) {
vpContent.setCurrentItem(page, false);
}
private OnPageChangeListener mPageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
chosenTab(arg0);
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
};
private void chosenTab(int currentItem) {
tv1.setTextColor(Color.parseColor("#FFFFFF"));
tv2.setTextColor(Color.parseColor("#FFFFFF"));
tv3.setTextColor(Color.parseColor("#FFFFFF"));
tv4.setTextColor(Color.parseColor("#FFFFFF"));
switch (currentItem) {
case FIRST_PAGE:
tv1.setTextColor(Color.parseColor("#FFFF00"));
break;
case SECOND_PAGE:
tv2.setTextColor(Color.parseColor("#FFFF00"));
break;
case THIRD_PAGE:
tv3.setTextColor(Color.parseColor("#FFFF00"));
break;
case FOURTH_PAGE:
tv4.setTextColor(Color.parseColor("#FFFF00"));
break;
default:
break;
}
}
private void initPageView() {
// TODO Auto-generated method stub
mFragment1 = new MyFragment1();
mFragment2 = new MyFragment2();
mFragment3 = new MyFragment3();
mFragment4 = new MyFragment4();
mFragments = new ArrayList<CommonFragment>();
mFragments.add(mFragment1);
mFragments.add(mFragment2);
mFragments.add(mFragment3);
mFragments.add(mFragment4);
mTitles = new ArrayList<String>();
mTitles.add(mFragment1.getTitle());
mTitles.add(mFragment2.getTitle());
mTitles.add(mFragment3.getTitle());
mTitles.add(mFragment4.getTitle());
mFragmentAdapter = new MainFragmentAdapter(getSupportFragmentManager(),
mFragments, mTitles);
myFragmentSaveStatePagerAdapter = new CommonFragmentSaveStatePagerAdapter(
getSupportFragmentManager(), vpContent, mFragments);
vpContent.setAdapter(myFragmentSaveStatePagerAdapter);
// 设置默认的窗口,就是打开应用后第一眼看到的
setCurPage(FIRST_PAGE);
// 如果系统内存足够,就能实现fragment的缓存,参数是最大缓存数,如果数据量太大,就不要这样设置,耗内存
// vpContent.setOffscreenPageLimit(5);
}
/** 开启系统设置页面 **/
protected void IntentToMoreActivity() {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, MoreActivity.class);
startActivity(intent);
}
/**
* 初始化app
*/
private void initApp() {
}
/** 注册配置请求完成广播 */
public void registerBoradcastReceiver() {
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction("main_action");
// 注册广播
this.registerReceiver(mBroadcastReceiver, myIntentFilter);
isRegisterBroadcast = true;
}
/** 取消注册的广播 */
public void unRegisterBoradcastReceiver() {
if (isRegisterBroadcast) {
this.unregisterReceiver(mBroadcastReceiver);
}
}
/** 广播接收器 */
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
// 执行接受到广播后的相关操作,可以操作UI,但不能进行耗时操作
}
};
/**
* 跳转到对应的activity
*
* @param c
*/
public void intentToActivity(Class c) {
if (c == null) {
return;
}
Intent intent = new Intent(this, c);
startActivity(intent);
}
public void intentToActivityForResult(int requestCode, Class c) {
if (c == null) {
return;
}
Intent intent = new Intent(mContext, c);
((Activity) mContext).startActivityForResult(intent, requestCode);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
// 如果有提示退出对话框,可以在这里写代码
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
/**
* 隐藏应用,返回到桌面
*/
public void hide() {
// 保存设置信息
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
首页的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/main_head"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#654321"
android:orientation="horizontal"
android:paddingLeft="12dp"
android:paddingRight="12dp" >
<TextView
android:id="@+id/main_text1"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="page1"
android:textColor="#b3ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/main_text2"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="page2"
android:textColor="#b3ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/main_text3"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="page3"
android:textColor="#b3ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/main_text4"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="page4"
android:textColor="#b3ffffff"
android:textSize="15dp" />
<LinearLayout
android:id="@+id/main_menu_layout"
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/main_menu_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/main_more_icon"
android:gravity="center"
android:textColor="#ffffff" />
</LinearLayout>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/v50_main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_head" />
</RelativeLayout>
关于fragment,实现了滑动切换的效果,需要对Fragment进行封装,封装后的类名是CommonFragment,添加滑动效果
package com.example.activitymode;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
public class CommonFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void startActivity(Intent intent) {
super.startActivity(intent);
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_left_out);
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_left_out);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
public void onBackPressed() {
}
public void onTabChange() {
}
}
首页里面的一个Fragment,由于其他3个都是类似的,所以只提供一个代码
package com.example.activitymode;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment1 extends CommonFragment {
public static String title = "MyFragment1";
private View rootView;
public String getTitle() {
// TODO Auto-generated method stub
return title;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
rootView = inflater
.inflate(R.layout.fragment1_layout, container, false);
return rootView;
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#123456"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#ffffff"
android:text="The first page" />
</LinearLayout>
适配器:
CommonFragmentPagerAdapter
viewpager的fragment適配器,fragment管理类FragmentManager,不显示的fragment采取销毁策略
缓存策略为显示页面左边第一个以及右边第一个
package com.example.activitymode;
import java.util.ArrayList;
import java.util.List;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
/**
* viewpager的fragment適配器,fragment管理类FragmentManager,自带缓存策略的适配器,
* 缓存策略为显示页面左边第一个以及右边第一个
*
*
*/
public abstract class CommonFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "CommonFragmentPagerAdapter";
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;
private List<Fragment> mFragments;
public CommonFragmentPagerAdapter(FragmentManager fm) {
mFragmentManager = fm;
}
public CommonFragmentPagerAdapter(FragmentManager fm,
ArrayList<Fragment> fragments) {
mFragmentManager = fm;
this.mFragments = fragments;
}
public abstract Fragment getItem(int position);
@Override
public int getCount() {
return mFragments.size();
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
@Override
public void startUpdate(View container) {
}
@Override
public Object instantiateItem(View container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
// mCurTransaction.detach(fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public void destroyItem(View container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
mCurTransaction.detach((Fragment) object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
Fragment fragment = (Fragment) object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
super.setPrimaryItem(container, position, object);
}
@Override
public void finishUpdate(View container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
return position;
}
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
@Override
public void notifyDataSetChanged() {
// TODO Auto-generated method stub
// if (mCurTransaction == null) {
// mCurTransaction = mFragmentManager.beginTransaction();
// }
// final long itemId = getItemId(position);
// String name = makeFragmentName(container.getId(), itemId);
// Fragment fragment = mFragmentManager.findFragmentByTag(name);
// if (fragment != null) {
// mCurTransaction.detach(fragment);
// mCurTransaction.attach(fragment);
// }
super.notifyDataSetChanged();
}
}
package com.example.activitymode;
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
public class CommonFragmentSaveStatePagerAdapter extends PagerAdapter {
private List<CommonFragment> fragments;
private FragmentManager fragmentManager;
private ViewPager viewPager;
private int currentPageIndex = 0;
private OnExtraPageChangeListener onExtraPageChangeListener;
public CommonFragmentSaveStatePagerAdapter(FragmentManager fragmentManager,
ViewPager viewPager, List<CommonFragment> fragments) {
this.fragments = fragments;
this.fragmentManager = fragmentManager;
this.viewPager = viewPager;
this.viewPager.setAdapter(this);
this.viewPager.setOnPageChangeListener(mOnPageChangeListener);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(fragments.get(position).getView()); // 移出viewpager两边之外的page布局
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = fragments.get(position);
if (!fragment.isAdded()) {
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.add(fragment, fragment.getClass().getSimpleName());
ft.commit();
/**
* 在用FragmentTransaction.commit()方法提交FragmentTransaction对象后
* 会在进程的主线程中,用异步的方式来执行。 如果想要立即执行这个等待中的操作,就要调用这个方法(只能在主线程中调用)。
* 要注意的是,所有的回调和相关的行为都会在这个调用中被执行完成,因此要仔细确认这个方法的调用位置。
*/
fragmentManager.executePendingTransactions();
}
if (fragment.getView().getParent() == null) {
container.addView(fragment.getView());
}
return fragment.getView();
}
public int getCurrentPageIndex() {
return currentPageIndex;
}
public OnExtraPageChangeListener getOnExtraPageChangeListener() {
return onExtraPageChangeListener;
}
public void setOnExtraPageChangeListener(
OnExtraPageChangeListener onExtraPageChangeListener) {
this.onExtraPageChangeListener = onExtraPageChangeListener;
}
private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
fragments.get(currentPageIndex).onPause();
if (fragments.get(arg0).isAdded()) {
fragments.get(arg0).onResume();
}
currentPageIndex = arg0;
if (null != onExtraPageChangeListener) {
onExtraPageChangeListener.onExtraPageSelected(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
if (null != onExtraPageChangeListener) {
onExtraPageChangeListener.onExtraPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
if (null != onExtraPageChangeListener) {
onExtraPageChangeListener.onExtraPageScrollStateChanged(arg0);
}
}
};
static class OnExtraPageChangeListener {
public void onExtraPageScrolled(int i, float v, int i2) {
}
public void onExtraPageSelected(int i) {
}
public void onExtraPageScrollStateChanged(int i) {
}
}
}
其他非首页的Activity,这里的试例是MoreActivity
package com.example.activitymode;
import android.os.Bundle;
public class MoreActivity extends CommonActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.more_activity_layout);
setTitle("菜单");
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Menu activity"
android:gravity="center"
android:background="#ffffff"/>
</LinearLayout>
demo项目代码
http://pan.baidu.com/s/1i3o9bVJ
来源:oschina
链接:https://my.oschina.net/u/2335739/blog/531849