public class TimeLimitPurchaseScrollView 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 TimeLimitPurchaseAdapter mAdapter;
/**
* 每屏幕最多显示的个数
*/
private int mCountOneScreen;
/**
* 屏幕的宽度
*/
private int mScreenWitdh;
/**
* 保存View与位置的键值对
*/
private Map<View, Integer> mViewPos = new HashMap<View, Integer>();
public TimeLimitPurchaseScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
// 获得屏幕宽度
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWitdh = outMetrics.widthPixels;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mContainer = (LinearLayout) getChildAt(0);
}
/**
* 加载下一张图片
*/
protected void loadNextImg()
{
// 数组边界值计算
if (mCurrentIndex == mAdapter.getCount() - 1)
{
return;
}
//移除第一张图片,且将水平滚动位置置0
scrollTo(0, 0);
mViewPos.remove(mContainer.getChildAt(0));
mContainer.removeViewAt(0);
//获取下一张图片,并且设置onclick事件,且加入容器中
View view = mAdapter.getView(++mCurrentIndex, null, mContainer);
view.setOnClickListener(this);
mContainer.addView(view);
mViewPos.put(view, mCurrentIndex);
//当前第一张图片小标
mFristIndex++;
//如果设置了滚动监听则触发
if (mListener != null)
{
notifyCurrentImgChanged();
}
}
/**
* 加载前一张图片
*/
protected void loadPreImg()
{
//如果当前已经是第一张,则返回
if (mFristIndex == 0)
return;
//获得当前应该显示为第一张图片的下标
int index = mCurrentIndex - mCountOneScreen;
if (index >= 0)
{
// mContainer = (LinearLayout) getChildAt(0);
//移除最后一张
int oldViewPos = mContainer.getChildCount() - 1;
mViewPos.remove(mContainer.getChildAt(oldViewPos));
mContainer.removeViewAt(oldViewPos);
//将此View放入第一个位置
View view = mAdapter.getView(index, null, mContainer);
mViewPos.put(view, index);
mContainer.addView(view, 0);
view.setOnClickListener(this);
//水平滚动位置向左移动view的宽度个像素
scrollTo(mChildWidth, 0);
//当前位置--,当前第一个显示的下标--
mCurrentIndex--;
mFristIndex--;
//回调
if (mListener != null)
{
notifyCurrentImgChanged();
}
}
}
/**
* 滑动时的回调
*/
public void notifyCurrentImgChanged()
{
//先清除所有的背景色,点击时会设置为蓝色
for (int i = 0; i < mContainer.getChildCount(); i++)
{
mContainer.getChildAt(i).setBackgroundColor(Color.WHITE);
}
mListener.onCurrentImgChanged(mFristIndex, mContainer.getChildAt(0));
}
/**
* 初始化数据,设置数据适配器
*
* @param mAdapter
*/
public void initDatas(TimeLimitPurchaseAdapter mAdapter)
{
this.mAdapter = mAdapter;
mContainer = (LinearLayout) getChildAt(0);
// 获得适配器中第一个View
final View view = mAdapter.getView(0, null, mContainer);
mContainer.addView(view);
// 强制计算当前View的宽和高
if (mChildWidth == 0 && mChildHeight == 0)
{
int w = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
int h = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
view.measure(w, h);
mChildHeight = view.getMeasuredHeight();
mChildWidth = view.getMeasuredWidth();
Log.e(TAG, view.getMeasuredWidth() + "," + view.getMeasuredHeight());
mChildHeight = view.getMeasuredHeight();
// 计算每次加载多少个View
mCountOneScreen = (mScreenWitdh / mChildWidth == 0)?mScreenWitdh / mChildWidth+1:mScreenWitdh / mChildWidth+2;
Log.e(TAG, "mCountOneScreen = " + mCountOneScreen
+ " ,mChildWidth = " + mChildWidth);
}
//初始化第一屏幕的元素
initFirstScreenChildren(mCountOneScreen);
}
/**
* 加载第一屏的View
*
* @param mCountOneScreen
*/
public void initFirstScreenChildren(int mCountOneScreen)
{
mContainer = (LinearLayout) getChildAt(0);
mContainer.removeAllViews();
mViewPos.clear();
for (int i = 0; i < mCountOneScreen; i++)
{
View view = mAdapter.getView(i, null, mContainer);
view.setOnClickListener(this);
mContainer.addView(view);
mViewPos.put(view, i);
mCurrentIndex = i;
}
if (mListener != null)
{
notifyCurrentImgChanged();
}
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
switch (ev.getAction())
{
case MotionEvent.ACTION_MOVE:
// Log.e(TAG, getScrollX() + "");
int scrollX = getScrollX();
// 如果当前scrollX为view的宽度,加载下一张,移除第一张
if (scrollX >= mChildWidth)
{
loadNextImg();
}
// 如果当前scrollX = 0, 往前设置一张,移除最后一张
if (scrollX == 0)
{
loadPreImg();
}
break;
}
return super.onTouchEvent(ev);
}
@Override
public void onClick(View v)
{
if (mOnClickListener != null)
{
for (int i = 0; i < mContainer.getChildCount(); i++)
{
mContainer.getChildAt(i).setBackgroundColor(Color.WHITE);
}
mOnClickListener.onClick(v, mViewPos.get(v));
}
}
public void setOnItemClickListener(OnItemClickListener mOnClickListener)
{
this.mOnClickListener = mOnClickListener;
}
public void setCurrentImageChangeListener(
CurrentImageChangeListener mListener)
{
this.mListener = mListener;
}
}
//布局显示
<com.emzk.app.view.TimeLimitPurchaseScrollView
android:id="@+id/id_timeLimitPurchaseScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/id_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</com.emzk.app.view.TimeLimitPurchaseScrollView>
mStormAdapter = new TimeLimitPurchaseAdapter(getActivity(),mStormListData);
timeLimitPurchaseScrollView.initDatas(mStormAdapter);
timeLimitPurchaseScrollView.setOnItemClickListener(new TimeLimitPurchaseScrollView.OnItemClickListener() {
@Override
public void onClick(View view, int pos) {
Intent intent=new Intent(getActivity(),CommodityDetailsPageActivity.class);
// intent.putExtra("orderId", list.get(position).getOrderId());
startActivity(intent);
}
});
mStormAdapter.notifyDataSetChanged();
public class TimeLimitPurchaseAdapter extends BaseAdapter {
Context context;
List<TimeLimitPurchase> listData;
public TimeLimitPurchaseAdapter(Context context,
List<TimeLimitPurchase> listData) {
this.context = context;
this.listData = listData;
}
@Override
public int getCount() {
return listData.size();
}
@Override
public Object getItem(int position) {
return listData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
final int pos = position;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.time_limit_purchase_item, parent, false);
viewHolder = new ViewHolder();
// viewHolder.imageView = (ImageView) convertView
// .findViewById(R.id.index_gallery_item_image);
viewHolder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
viewHolder.tv_price = (TextView) convertView.findViewById(R.id.tv_price);
viewHolder.tv_bonus = (TextView) convertView.findViewById(R.id.tv_bonus);
viewHolder.tv_count_down = (TextView) convertView.findViewById(R.id.tv_count_down);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
resetViewHolder(viewHolder);
}
// ImageLoader.getInstance().displayImage(listData.get(pos).getPigUrl(), viewHolder.imageView);
viewHolder.tv_title.setText(listData.get(pos).getTitle());
viewHolder.tv_price.setText("¥" + listData.get(pos).getPrice());
viewHolder.tv_bonus.setText(listData.get(pos).getBonus() + "元");
viewHolder.tv_count_down.setText(listData.get(pos).getCount_down());
return convertView;
}
class ViewHolder {
// ImageView imageView;
TextView tv_title;
TextView tv_price;
TextView tv_bonus;
TextView tv_count_down;
}
protected void resetViewHolder(ViewHolder viewHolder) {
// viewHolder.imageView.setImageBitmap(null);
viewHolder.tv_title.setText("");
viewHolder.tv_price.setText("");
viewHolder.tv_bonus.setText("");
}
}
time_limit_purchase_item布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="300dp"
android:layout_height="130dp"
android:layout_marginLeft="5dp"
android:background="@drawable/circle_rectangle"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="3"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/summer_love"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:textColor="#666666"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:textColor="#383838"
android:textSize="16sp"
android:text="99.00"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_marginLeft="10dp"
android:layout_height="wrap_content">
<Button
android:id="@+id/tv_bonus"
android:layout_width="80dp"
android:layout_height="18dp"
android:textColor="#E83033"
android:paddingLeft="10dp"
android:background="@drawable/bonus_oval_background"
android:text="800.5元"
/>
<Button
android:layout_width="18dp"
android:layout_height="18dp"
android:textColor="@color/white"
android:gravity="center"
android:background="@drawable/bonus_round_background"
android:text="@string/bonus"/>
</RelativeLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:background="#F2F2F2"
android:layout_marginTop="10dp"
android:layout_height="1dp"/>
<TextView
android:id="@+id/tv_count_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:textColor="#999999"
android:text="剩 3 天 10 时 15 分 43 秒"
/>
</LinearLayout>
<ImageView
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:src="@mipmap/leishi"/>
</LinearLayout>
</LinearLayout>
本文详细介绍了如何通过自定义HorizontalScrollView实现一个可以左右滑动的界面。内容涵盖布局设计和滚动逻辑的实现,为开发者提供了一个灵活的界面交互解决方案。

被折叠的 条评论
为什么被折叠?



