兼容包
一些高版本中功能,如果要在低版本中也可以正常使用,则需要兼容包,系统提供的兼容包v4,v7,v13,兼容包属于sdk开发包的扩展,属于第三方包
ViewPager
xml:
<android.support.v4.view.ViewPager
android:id="@+id/m_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
java:
ViewPager mPager = (ViewPager) findViewById(R.id.m_pager);
定义适配器:
class MyPagerAdapter extends PagerAdapter {
private int[] resIds = { R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5 };
private ImageView[] views;
public MyPagerAdapter() {
views = new ImageView[resIds.length];
for (int i = 0; i < resIds.length; i++) {
views[i] = createImageView(resIds[i]);
}
}
// 配置页面数量
@Override
public int getCount() {
return resIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
// 销毁--当视图从缓冲中移除出去时触发
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.e("m_tag","destroyItem:"+position);
//获取移除的视图
ImageView iv = views[position];
container.removeView(iv);
}
// 初始化--当有新的内容进入缓冲区时触发
@Override
public Object instantiateItem(ViewGroup container, int position) {
Log.e("m_tag","instantiateItem:"+position);
ImageView iv = views[position];
container.addView(iv);
return iv;
}
private ImageView createImageView(int resId) {
ImageView iv = new ImageView(ViewPagerActivity.this);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
// 显示的图片
iv.setImageResource(resId);
iv.setScaleType(ScaleType.CENTER_CROP);
return iv;
}
}
设置适配器
MyPagerAdapter adapter = new MyPagerAdapter();
mPager.setAdapter(adapter);
页面滑动监听
//ViewPager页面滑动监听
mPager.setOnPageChangeListener(new OnPageChangeListener() {
//当选中某个页面时触发(确认显示的新页面)
@Override
public void onPageSelected(int position) {
Log.e("m_tag", "onPageSelected:"+position);
((RadioButton)mGroup.getChildAt(position)).setChecked(true);
}
//正在滑动中
//position表示滑动中的第一个页面的下标
//offset滑动中第一个页面的偏移量(0-1)
//offsetInPixels滑动的第一个页面在屏幕外面的像素
@Override
public void onPageScrolled(int position, float offset, int offsetInPixels) {
Log.e("m_tag", "onPageScrolled:"+position+" offset:"+offset+" offsetInPixels:"+offsetInPixels);
}
//1表示开始拖动 2表示停止拖动
@Override
public void onPageScrollStateChanged(int state) {
Log.e("m_tag", "state:"+state);
}
});
ViewPager页面设置
mPager.setCurrentItem(0, true); //设置显示的页面下标
mPager.getCurrentItem() 获取当前显示的下标
mPager.setPageMargin(20); //设置页面间距
ViewPager适配器缓存
原理:在显示的时候将位置和视图对象记录起来,在销毁视图时将要销毁的视图从显示记录中移除出去,将移除出去的视图对象添加到缓存队列中,以便于
下一个初始的时候从缓存中直接获取
public class XPagerAdapter extends PagerAdapter {
//显示的视图
private Map<Integer,View> showViews;
//缓存队列
private LinkedList<View> caches;
//数据源
private int[] resIds = { R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5 };
private Context context;
public XPagerAdapter(Context context){
this.context = context;
showViews = new HashMap<Integer, View>();
caches = new LinkedList<View>();
}
@Override
public int getCount() {
return resIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
//获取要移除的视图(之前显示过的)
View v = showViews.get(position);
container.removeView(v);
//将移除的视图对象记录起来
caches.addLast(v);
showViews.remove(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//给数据配置显示视图
ImageView iv;
//如果缓存区中有视图,可以直接拿来显示
if(!caches.isEmpty()){
iv = (ImageView) caches.removeFirst();
}else{
iv = createImageView();
}
iv.setImageResource(resIds[position]);
container.addView(iv);
//将当前显示的视图用一位置记录起来
showViews.put(position, iv);
return iv;
}
private ImageView createImageView() {
ImageView iv = new ImageView(context);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
iv.setScaleType(ScaleType.CENTER_CROP);
return iv;
}
}
Fragment
Android3.0之后提出的新功能,低版本使用v4包中提供的Fragment以及FragmentActivity来实现碎片化布局
作用:分担Activity的压力,可以灵活轻巧的嵌入到Activity中,由Activity管理哪个显示哪个隐藏,实现多业务的展示效果
Fragment不能单独使用,必须要嵌入到Activity中由Activity管理
Fragment添加到Activity的方式
xml中添加,静态注册
//ListActivity,自带一个ListView
public class LeftFragment extends ListFragment {
private String[] items = { "Java基础", "Java高级编程", "数据库", "Android基础",
"Android进阶", "项目实战", "项目管理 " };
// 当前Fragment要显示的布局
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
// 当布局加载完毕时触发
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ArrayAdapter<String> adapter= new ArrayAdapter<String>
//给自带的ListView设置适配器
setListAdapter(adapter);
}
//ListFragment中自带的ListView的item点击监听
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String str = items[position];
Toast.makeText(getActivity(), "点击了:"+str, Toast.LENGTH_SHORT).show();
}
}
在Activity(FragmentActivity)的布局中使用fragment标签添加
<fragment
android:id="@+id/fragment_left"
android:layout_width="200dp"
android:layout_height="match_parent"
android:name="com.xykj.fragment.LeftFragment" />
注意:低版本Activity需要继承FragmentActivity
public class MyActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_my);
}
}
Java中添加
1、定义内容显示的碎片对象
public class RightFragment extends Fragment {
public static RightFragment newInstance(String str,int position){
RightFragment f = new RightFragment();
Bundle b = new Bundle();
b.putString("content", str);
b.putInt("pos", position);
//设置内部参数(只能在显示之前使用)
f.setArguments(b);
return f;
}
//配置Fragment的布局
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_right, null);
return layout;
}
//布局创建成功
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
TextView tv = (TextView) view.findViewById(R.id.tv);
//显示内容
//获取内部参数中的内容
String content = getArguments().getString("content");
tv.setText(content);
}
//获取当前碎片显示的下标
public int getIndex(){
return getArguments().getInt("pos");
}
}
2、获取FragmentManager管理碎片
// 获取碎片管理器
FragmentManager fm = getFragmentManager();
// 检测布局中右侧(内容区)是否有内容碎片在显示
RightFragment fragment = (RightFragment) fm
.findFragmentById(R.id.content);
if (fragment == null || position != fragment.getIndex()) {
// 如果有则判断显示的下标跟当前要显示的是不是一样的
// 不一样则替换新的内容进来
// 如果没有内容显示,显示新内容
fragment = RightFragment.newInstance(str, position);
//获取碎片操作工具(对碎片进行显示、隐藏、替换、添加、移除、注册、取消注册)
FragmentTransaction ft = fm.beginTransaction();
//添加替换动画
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
ft.replace(R.id.content, fragment); //替换新的碎片进来
ft.commit();
}
注意:ft.commit()的提交事务的操作必须在Activity保存状态之前使用,如果在状态保存之后,那么需要使用
ft.commitAllowingStateLoss()提交事务
Fragment操作时可以将操作添加回退栈
//回退栈
ft.addToBackStack(null);
添加回退栈可以实现按返回键回到上一个Fragment效果
Java动态管理(选项卡)
//假设显示过的Fragment对象,我都记录起来,当记录为null则表示没显示过,当记录非null表示显示过
private Fragment[] fragmens; //记录曾经显示过的Fragment对象
//记录当前显示的下标
private int currentIndex=-1;
....Activity onCreate...
//默认显示0
showFragment(0);
............
/**
* 根据下标显示新的内容(0显示消息,1好友,2动态)
* @param index
*/
private void showFragment(int index){
//新的页面跟当前的页面不一样
if(index != currentIndex){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
//隐藏旧的 显示新的(如果有过显示,恢复,如果没有过显示,创建,添加)
if(currentIndex!=-1){
ft.detach(fragmens[currentIndex]); //取消关联(会导致Fragment的视图销毁)
}
//显示新的
if(fragmens[index]!=null){
ft.attach(fragmens[index]); //恢复关联(到让Fragment重新创建视图)
}else{
//第一次需要显示
fragmens[index]=createFragment(index);
//第一次显示出来(添加到容器)
ft.add(R.id.content, fragmens[index]);
}
ft.commit();
currentIndex = index;
}
}
private Fragment createFragment(int index){
switch (index) {
case 0:
return new FragmentMsg();
case 1:
return new FragmentFriend();
case 2:
return new FragmentMe();
}
return null;
}
退出Activity时记得移除曾经显示过的内容
@Override
protected void onDestroy() {
//移除曾经显示过的Fragment
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
for(Fragment f : fragmens){
if(null != f){
ft.remove(f);
}
}
//提交事务,允许状态丢失也要提交
ft.commitAllowingStateLoss();
super.onDestroy();
}