展会信息港展会大全

自定义gallery,避免选中项总在中间的问题
来源:互联网   发布日期:2015-10-03 10:45:12   浏览:1807次  

导读:最近做了一个小功能,实现类似gallery的效果,但需要选中项在第一个,且不希望拉到最前面会有空余空间,在尝试使用android自带的gallery未能达到效果的情况下,自己写了个简单但能...

最近做了一个小功能,实现类似gallery的效果,但需要选中项在第一个,且不希望拉到最前面会有空余空间,在尝试使用android自带的gallery未能达到效果的情况下,自己写了个简单但能满足功能的东东。首先分享一下对于gallery的使用。

首先面对的是不希望拉到最前面有空白,所以参考网上的例子,通过setselection设置选中一个较大的数字,当然,这里要求在adapter中设置getcount方法里返回int的最大值,以下是getview内的代码,cacheView是类里定义的一个缓存itemview的HashMap<Integer,View>对象,然后通过position%list.size()获取已经在缓存内的view,其中list就是数据源数据集合

convertView = cacheView.get(position%list.size());

if(convertView== null){

convertView = mInflater.inflate(layoutId, null);

ImageView iv =(ImageView) convertView.findViewById(R.id.image);

iv.setBackgroundResource(list.get(position%list.size()));

cacheView.put(position%list.size(), convertView);

}

return convertView;

这样做的效果就是一开始就处于满屏的,且左右拉会有循环显示的效果,但选中项仍然在中间,且拖拉结束时,会自动选中一个

鉴于以上不能满足需求,我尝试了继承gallery重写里面的onTouchEvent,onFling方法,可以通过MotionEvent.ACTION_UP以及onFling 直接return false;达到拖拉时不自动选中,但是项的单击事件也会无法使用,即OnItemClickListener无法触发,在来回纠结并尝试了很久后,还是放弃了

在网上看到有人提出一个使用ScrollView自己实现gallery的思路,于是便写了一个功能简单,但便于使用的代码,在此做一分享,希望给大家一些思路

public class MyGallery extends HorizontalScrollView {

public MyGallery(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyGallery(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

private List<ImageView> imageViews =new ArrayList<ImageView>();//图片view对象,初始化后生成

private List<TextView> textViews =new ArrayList<TextView>();//文本view对象,初始化后生成

private Context mContext;//调用本view的activity

private int mWidth;//宽度onlayout里赋值

private int selectedItemIndex = -1;//选中的项下标

private int displayNum = 5;//要显示项的数量

private int defaultIndex = 0;//默认选中的下标

private int itemWidth;//每一项的宽度

private OnClickListener itemClickListener;//点击每项的事件,初始化传入,可以通过onclick中的view内的tag获得postion区分

private Handler handler;//用来处理选中滚动事件

private int inoutTime = 200;//放大缩小所耗时间

private float scale = 1.2f;//放大后的比例

private LayoutInflater mInflater;

private List<IWantType> typeList;//类别列表

private int adjust =-5;//调整移动位置

public MyGallery(Context context) {

super(context);

this.mContext = context;

}

/**

* 完成布局时根据宽度与显示的数量初始化item布局

*/

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

if(this.mWidth != this.getWidth()){

this.mWidth = this.getWidth();

this.itemWidth = this.mWidth/this.displayNum;

initImages(itemClickListener);

}

}

/**

* 初始化

* @param context

* @param images

* @param itemClickListener

*/

public void init(Context context,List<IWantType> typeList,OnClickListener itemClickListener,int defaultIndex) {

this.typeList = typeList;

this.mContext = context;

this.mInflater = LayoutInflater.from(context);

this.defaultIndex = defaultIndex;

this.setVerticalScrollBarEnabled(false); //禁用垂直滚动

this.setHorizontalScrollBarEnabled(false); //禁用水平滚动

this.itemClickListener = itemClickListener;

this.handler =new Handler(){

public void handleMessage(Message msg) {

if(msg.arg1>msg.arg2){

int each = (msg.arg1-msg.arg2)/10;

if(msg.arg2+each<msg.arg1 && each>0){

scrollTo(msg.arg2+each+adjust, 0);

}else{

scrollTo(msg.arg1+adjust, 0);

}

Message message = new Message();

message.arg1 =msg.arg1;

if(each!=0){

message.arg2 =msg.arg2+each;

sendMessageDelayed(message, 1);

}

}else{

int each = (msg.arg2-msg.arg1)/10;

if(msg.arg2-each>msg.arg1 && each>0){

scrollTo(msg.arg2-each+adjust, 0);

}else{

scrollTo(msg.arg1+adjust, 0);

}

Message message = new Message();

message.arg1 =msg.arg1;

if(each!=0){

message.arg2 =msg.arg2-each;

sendMessageDelayed(message, 1);

}

}

};

};

}

/**

* 绑定图片项

* @param clickListener

*/

private void initImages(OnClickListener clickListener){

this.removeAllViews();

LinearLayout ll = new LinearLayout(mContext);

ll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

for(int i=0;i<typeList.size();i++){

IWantType iWantType = typeList.get(i);

FrameLayout llitem =(FrameLayout) mInflater.inflate(R.layout.mygallery_item, null);

llitem.setLayoutParams(new RelativeLayout.LayoutParams(this.itemWidth , LayoutParams.WRAP_CONTENT));

ImageView image =(ImageView) llitem.findViewById(R.id.image);

image.setTag(i);

image.setOnClickListener(clickListener);

TextView textView = (TextView) llitem.findViewById(R.id.text);

textView.setText(iWantType.name);

textView.setTextColor(Color.parseColor(iWantType.color));

NeighborApplication.getSelf().getPictrueManager().download(iWantType.pic, image);

ll.addView(llitem);

imageViews.add(image);

textViews.add(textView);

}

this.addView(ll);

selectItem(defaultIndex);

}

/**

* 获取某个imageView

* @param postion

* @return

*/

public ImageView getItemView(int postion){

return imageViews.get(postion);

}

/**

* 选中某个item

* @param position

*/

public void selectItem(Integer position){

if(position!=selectedItemIndex){

if(selectedItemIndex!=-1){

imageViews.get(selectedItemIndex).startAnimation(scaleIn(inoutTime));

textViews.get(selectedItemIndex).startAnimation(scaleIn(inoutTime));

}

imageViews.get(position).startAnimation(scaleOut(inoutTime));

textViews.get(position).startAnimation(scaleOut(inoutTime));

selectedItemIndex = position;

Message msg=new Message();

msg.arg1 = position*itemWidth;

msg.arg2 = getScrollX();

this.handler.sendMessage(msg);

}

}

/**

* 选择下一个

* @return 选中的index

*/

public int selectNext(){

if(selectedItemIndex+1<imageViews.size()){

selectItem(selectedItemIndex+1);

}

return selectedItemIndex;

}

/**

* 选择上一个

* @return 选中的index

*/

public int selectPrev(){

if(selectedItemIndex>0){

selectItem(selectedItemIndex-1);

}

return selectedItemIndex;

}

/**

* 以自身中心为圆心扩放

* @param 持续时间

* @return

*/

private Animation scaleOut(long time){

Animation animation =new ScaleAnimation(1,scale,1,scale,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);

animation.setDuration(time);

animation.setFillAfter(true);

return animation;

}

/**

* 以自身中心为圆心收缩

* @param 持续时间

* @return

*/

private Animation scaleIn(long time){

Animation animation =new ScaleAnimation(scale,1,scale,1,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);

animation.setDuration(time);

return animation;

}

其中iwanttype类是一个实体类,大家可以根据自己的需求更改,主要用于给项绑定数据

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

>

<ImageView

android:id="@+id/image"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

/>

<TextView

android:id="@+id/text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="60dip"

/>

</FrameLayout>

以上是item项布局文件,就一个图片和下面的文字,因为我这里要文字覆盖一部分图片,所以使用的framelayout,大家可以按需使用

总体思路是,根据数据源,在一个LinearLayout里循环插入imageview以及textview,并根据外部传入的click事件绑定点击事件,这里需要注意的是,在自己写onclick方法时,需要根据view的getTag来区分每项= =没有itemclick那么方便了。。不过还是可以使用的,我这里选中项是在最前面的,大家也可以根据需求修改handler里的控制滚动代码,这样一个简单实用的gallery就完工了~~~

摘自 chenghaoorange的专栏

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港