Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果

android:layout_width=“match_parent”

android:layout_height=“match_parent”

<HorizontalScrollView

android:layout_width=“wrap_content”

android:layout_height=“150dp”

android:layout_gravity=“center_vertical”

android:background=“#AA444444”

android:scrollbars=“none” >

<LinearLayout

android:id=“@+id/id_gallery”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_gravity=“center_vertical”

android:orientation=“horizontal” >

很简单,就一个HorizontalScrollView内部有个水平方向的LinearLayout

MainActivity:

package com.example.zhy_horizontalscrollview;

import android.app.Activity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.Window;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

public class MainActivity extends Activity

{

private LinearLayout mGallery;

private int[] mImgIds;

private LayoutInflater mInflater;

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_main);

mInflater = LayoutInflater.from(this);

initData();

initView();

}

private void initData()

{

mImgIds = new int[] { R.drawable.a, R.drawable.b, R.drawable.c,

R.drawable.d, R.drawable.e, R.drawable.f, R.drawable.g,

R.drawable.h, R.drawable.l };

}

private void initView()

{

mGallery = (LinearLayout) findViewById(R.id.id_gallery);

for (int i = 0; i < mImgIds.length; i++)

{

View view = mInflater.inflate(R.layout.activity_index_gallery_item,

mGallery, false);

ImageView img = (ImageView) view

.findViewById(R.id.id_index_gallery_item_image);

img.setImageResource(mImgIds[i]);

TextView txt = (TextView) view

.findViewById(R.id.id_index_gallery_item_text);

txt.setText("some info ");

mGallery.addView(view);

}

}

}

很简单,我预先准备了一些图片直接放在了Drawble下,然后循环加入HorizontalScrollView的LinearLayout中即可,Item的布局就省了,后面会贴源码。

效果图:

效果还是不错的~如果只需要简单展示几张图片,直接用就可以了。

下面准备进入正题,HorizontalScrollView不管里面多少View都是不会回收的,当达到一定量的时候会发生OOM,下面介绍如何改写HorizontalScollView实现文章开始所说的效果。

2、自定义HorizontalScrollView

思想:

1、首先根据屏幕的大小和Item的大小,计算可以一个屏幕最多可以加载多少个Item,然后加载该数量Item。

2、当用户右滑(从右向左),滑动到一定距离时,加载下一张,删除第一张

3、当用户左滑(从左向右),滑动到一定距离时,加载上一张,删除最后一张

看下最后的效果图:

为了增加一定的趣味,做了一个类似上面的相册效果,支持拖动时自动变化,和点击变化~~是不是很赞~

1、首先看布局文件:

<LinearLayout 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”

android:background=“@android:color/white”

android:orientation=“vertical” >

<FrameLayout

android:layout_width=“fill_parent”

android:layout_height=“0dp”

android:layout_weight=“1” >

<ImageView

android:id=“@+id/id_content”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”

android:layout_gravity=“center”

android:layout_margin=“10dp”

android:scaleType=“centerCrop”

android:src=“@drawable/ic_launcher” />

<com.example.zhy_horizontalscrollview.MyHorizontalScrollView

android:id=“@+id/id_horizontalScrollView”

android:layout_width=“wrap_content”

android:layout_height=“150dp”

android:layout_gravity=“bottom”

android:background=“@android:color/white”

android:scrollbars=“none” >

<LinearLayout

android:id=“@+id/id_gallery”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_gravity=“center_vertical”

android:orientation=“horizontal” >

</com.example.zhy_horizontalscrollview.MyHorizontalScrollView>

没任何变化,除了把类名改成了我们自定义的类~

2、为了和国际接轨,我们也搞个Adapter,类似BaseAdapter

package com.example.zhy_horizontalscrollview;

import java.util.List;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

public class HorizontalScrollViewAdapter

{

private Context mContext;

private LayoutInflater mInflater;

private List mDatas;

public HorizontalScrollViewAdapter(Context context, List mDatas)

{

this.mContext = context;

mInflater = LayoutInflater.from(context);

this.mDatas = mDatas;

}

public int getCount()

{

return mDatas.size();

}

public Object getItem(int position)

{

return mDatas.get(position);

}

public long getItemId(int position)

{

return position;

}

public View getView(int position, View convertView, ViewGroup parent)

{

ViewHolder viewHolder = null;

if (convertView == null)

{

viewHolder = new ViewHolder();

convertView = mInflater.inflate(

R.layout.activity_index_gallery_item, parent, false);

viewHolder.mImg = (ImageView) convertView

.findViewById(R.id.id_index_gallery_item_image);

viewHolder.mText = (TextView) convertView

.findViewById(R.id.id_index_gallery_item_text);

convertView.setTag(viewHolder);

} else

{

viewHolder = (ViewHolder) convertView.getTag();

}

viewHolder.mImg.setImageResource(mDatas.get(position));

viewHolder.mText.setText("some info ");

return convertView;

}

private class ViewHolder

{

ImageView mImg;

TextView mText;

}

}

3、下面先看用法:

package com.example.zhy_horizontalscrollview;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import android.app.Activity;

import android.graphics.Color;

import android.os.Bundle;

import android.view.View;

import android.view.Window;

import android.widget.ImageView;

import com.example.zhy_horizontalscrollview.MyHorizontalScrollView.CurrentImageChangeListener;

import com.example.zhy_horizontalscrollview.MyHorizontalScrollView.OnItemClickListener;

public class MainActivity extends Activity

{

private MyHorizontalScrollView mHorizontalScrollView;

private HorizontalScrollViewAdapter mAdapter;

private ImageView mImg;

private List mDatas = new ArrayList(Arrays.asList(

R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d,

R.drawable.e, R.drawable.f, R.drawable.g, R.drawable.h,

R.drawable.l));

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_main);

mImg = (ImageView) findViewById(R.id.id_content);

mHorizontalScrollView = (MyHorizontalScrollView) findViewById(R.id.id_horizontalScrollView);

mAdapter = new HorizontalScrollViewAdapter(this, mDatas);

//添加滚动回调

mHorizontalScrollView

.setCurrentImageChangeListener(new CurrentImageChangeListener()

{

@Override

public void onCurrentImgChanged(int position,

View viewIndicator)

{

mImg.setImageResource(mDatas.get(position));

viewIndicator.setBackgroundColor(Color

.parseColor(“#AA024DA4”));

}

});

//添加点击回调

mHorizontalScrollView.setOnItemClickListener(new OnItemClickListener()

{

@Override

public void onClick(View view, int position)

{

mImg.setImageResource(mDatas.get(position));

view.setBackgroundColor(Color.parseColor(“#AA024DA4”));

}

});

//设置适配器

mHorizontalScrollView.initDatas(mAdapter);

}

}

用起来是不是有点像ListView,初始化数据适配器,然后设置数据适配器,然后就是设置各种回调~~

如果仅仅是一堆图片展示,类似商品切换,更见简单,就不需要设置滚动监听和点击监听了~

4、最后看自定义的MyHorizontalScrollView类

package com.example.zhy_horizontalscrollview;

import java.util.HashMap;

import java.util.Map;

import android.content.Context;

import android.graphics.Color;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

import android.widget.LinearLayout;

public class MyHorizontalScrollView extends HorizontalScrollView implements

OnClickListener

{

/**

  • 图片滚动时的回调接口

  • @author zhy

*/

public interface CurrentImageChangeListener

{

void onCurrentImgChanged(int position, View viewIndicator);

}

/**

  • 条目点击时的回调

  • @author zhy

*/

public interface OnItemClickListener

{

void onClick(View view, int pos);

}

private CurrentImageChangeListener mListener;

private OnItemClickListener mOnClickListener;

private static final String TAG = “MyHorizontalScrollView”;

/**

  • HorizontalListView中的LinearLayout

*/

private LinearLayout mContainer;

/**

  • 子元素的宽度

*/

private int mChildWidth;

/**

  • 子元素的高度

*/

private int mChildHeight;

/**

  • 当前最后一张图片的index

*/

private int mCurrentIndex;

/**

  • 当前第一张图片的下标

*/

private int mFristIndex;

/**

  • 当前第一个View

*/

private View mFirstView;

/**

  • 数据适配器

*/

private HorizontalScrollViewAdapter mAdapter;

/**

  • 每屏幕最多显示的个数

*/

private int mCountOneScreen;

/**

总结

本文讲解了我对Android开发现状的一些看法,也许有些人会觉得我的观点不对,但我认为没有绝对的对与错,一切交给时间去证明吧!愿与各位坚守的同胞们互相学习,共同进步!

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值