ViewPager使用

ViewPager是谷歌在jar包android-suppot-v4.jar内置的控件,主要是是view的左右滑动切换,有点类似于tabHost,不过tabHost是加载activity并且不能左右滑动。

谷歌的控件很多控件好像就是一个写的一样,用法几乎一模一样,只能说能在里面工作的人都太厉害了。

ViewPager用法和GridView,ListView差不多,就是设置适配器设置监听。

适配器:

package com.example.viewpagerimagetest;


import java.util.List;


import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;


public class adapter extends PagerAdapter
{


List<View> views;//viewPager加载的View集合


//构造方法,上下文context不用,写适配器习惯了就加进来了
public adapter(Context context, List<View> views)
{
this.views = views;
}


//加载view 的回调方法
@Override
public Object instantiateItem(ViewGroup container, int position)
{
container.addView(views.get(position));
return views.get(position);
}

//加载view的个数
@Override
public int getCount()
{
return views.size();
}

/*好像要这样写,原因不知道。官方解释:Determines whether a page View is associated with a specific key object as returned        by instantiateItem(ViewGroup, int). This method is required for a PagerAdapter to function properly.

true if view is associated with the key object object

*/
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == arg1;
}

//删除页卡,刚才不小心没在里面写东西划多几下会报错,求解释
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView(views.get(position));
}


}

布局:跟其他系统空间一模一样

<RelativeLayout 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"
    tools:context=".MainActivity" >


    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />


</RelativeLayout>


监听:

viewPager.setOnPageChangeListener(new OnPageChangeListener()

 {



@Override
public void onPageSelected(final int arg0)
{

//页卡改变时回调

}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{

//滑动的时候回调,arg0改变之后的页数,arg1是滑动的距离占屏幕宽度的百分比,如果写跟随滑动的游标可以用到
}


@Override
public void onPageScrollStateChanged(int arg0)
{

//这个东东没搞明白,Log出来总是0,1,2没什么规律
}

}

}


今天同事在做用viewpager来做类似图片浏览器的东西,滑动的页数太多了加载的图片太多会报oom,今晚回来想了一下,用这种思路,有点木,原则是显示一张bitmap释放一张bitmap,永远保证整个程序没被释放的图片只有三张,就是当前显示的,和上一张和下一张,其他的释放,更改一次页码释放一张。代码写的有点凌乱,不要见笑。除了这样方法有没有更好的方法啊,我看系统的图片浏览器特别流畅而且永远不会OOM,不知道是怎么实现的。

代码:


package com.example.viewpagerimagetest;


import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;


public class MainActivity extends Activity
{

//viewpager适配器
adapter adapter;

//viewpager的布局View
List<View> views = new ArrayList<View>();

//保持的3个bitmap对象
Bitmap[] bitmaps = new Bitmap[3];

//显示图片的控件
ImageView id1;

//用于判断是向前滑还是向后滑
int arg;

// 图片资源
int[] ids = new int[] { R.drawable.xu, R.drawable.xu1, R.drawable.a,
R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,
R.drawable.g, R.drawable.f, R.drawable.h, R.drawable.l,
R.drawable.k, R.drawable.m1, R.drawable.m2, R.drawable.m3,
R.drawable.m4, R.drawable.n1, R.drawable.n2, R.drawable.n3,
R.drawable.n4, R.drawable.n5, R.drawable.n6, R.drawable.n7,
R.drawable.n8, R.drawable.n9, R.drawable.n10, R.drawable.n11,
R.drawable.n12, R.drawable.n13, R.drawable.n14, R.drawable.n15,
R.drawable.n16, R.drawable.n17, R.drawable.n19, R.drawable.n20,
R.drawable.n22, R.drawable.n21, R.drawable.n24, R.drawable.n23,
R.drawable.n25 };


@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);


for (int i = 0; i < 36; i++)
{
views.add(getLayoutInflater().inflate(R.layout.cell, null));
if (i == 1 || i == 0)
{
id1 = (ImageView) views.get(i).findViewById(R.id.image);
Bitmap bitmap = BitmapFactory.decodeStream(getResources()
.openRawResource(ids[i]));
id1.setImageBitmap(bitmap);
if (i == 0)
{
bitmaps[1] = bitmap;
}
else
{
bitmaps[2] = bitmap;
}


}
}


adapter = new adapter(this, views);


ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);


viewPager.setOnPageChangeListener(new OnPageChangeListener()
{


@Override
public void onPageSelected(final int arg0)
{

// 当页数改变时启动线程加载控件和图片bitmap
new AsyncTask<Integer, Void, Integer>()
{
@Override
protected Integer doInBackground(Integer... params)
{
int i = 0;


if (arg0 < views.size() - 1 && (arg0 > arg))
{

//向后滑,释放第一张bitmap
if (bitmaps[0] != null && !bitmaps[0].isRecycled())
{
bitmaps[0].recycle();
System.out.println("+  "
+ bitmaps[0].isRecycled());
}

//让之前的当前页b变成前一页
bitmaps[0] = bitmaps[1];

// 让之前的之后一页变成当前页
bitmaps[1] = bitmaps[2];


id1 = (ImageView) views.get(arg0 + 1).findViewById(
R.id.image);
Bitmap bitmap = BitmapFactory
.decodeStream(getResources()
.openRawResource(ids[arg0 + 1]));
bitmaps[2] = bitmap;
id1.setImageBitmap(bitmap);
i = 2;
}
if (arg0 > 0 && (arg0 < arg))
{
if (bitmaps[2] != null && !bitmaps[2].isRecycled())
{
bitmaps[2].recycle();
System.out.println("-");
}
bitmaps[2] = bitmaps[1];
bitmaps[1] = bitmaps[0];


id1 = (ImageView) views.get(arg0 - 1).findViewById(
R.id.image);
Bitmap bitmap = BitmapFactory
.decodeStream(getResources()
.openRawResource(ids[arg0 - 1]));
bitmaps[0] = bitmap;
i = 0;
}


arg = arg0;
return i;
}


@Override
protected void onPostExecute(Integer result)
{
id1.setImageBitmap(bitmaps[result]);
}
}.execute(1);
}


@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}


@Override
public void onPageScrollStateChanged(int arg0)
{
}
});


viewPager.setAdapter(adapter);


}


@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}


}


出现了一个问题,如果划得太快会导致doInBackGround的没执行完,然后就报错了。但是不加线程又会导致手指离开屏幕的一刹那UI卡一下。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值