Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)
扫描二维码
随时随地手机看文章
本文内容:
1、横向ListView的所有实现思路;
2、其中一个最通用的思路HorizontalListView,并基于横向ListView开发一个简单的相册;
3、实现的横向ListView在点击、浏览时item背景会变色,并解决了listview里setSelected造成item的选择状态混乱的问题。
众所周知,ListView默认的方向是垂直的,但有些时候人们更喜欢横向ListView。纵观整个网络,横向ListView的实现思路如下:
1、在布局里用HorizontalScrollView包含一个ListView,参考这里;
2、利用GridView,把它的行数设为1行;
3、有人继承ListView构造了一个HorizontalScrollListView,参见:这里
4、国外一位大牛继承AdapterView
下面看源码:
这是Activity的布局文件:activity_main.xml
[html]
view plaincopyprint?
这是横向listview的每个item的布局,图片+文字,horizontal_list_item.xml
[html]
view plaincopyprint?
下面文件是selector_imageview_background.xml,这是大图片你点击浏览时背景发生变化的selector,没有啥实际作用。
[html]
view plaincopyprint?
下面是每个item的selector,在focus和select时颜色会发生变化:selector_item_background.xml
[html]
view plaincopyprint?
主程序:MainActivity.java
[java]
view plaincopyprint?package org.yanzi.testhorizontallistview; import org.yanzi.ui.HorizontalListView; import org.yanzi.ui.HorizontalListViewAdapter; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; public class MainActivity extends Activity { HorizontalListView hListView; HorizontalListViewAdapter hListViewAdapter; ImageView previewImg; View olderSelectView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void initUI(){ hListView = (HorizontalListView)findViewById(R.id.horizon_listview); previewImg = (ImageView)findViewById(R.id.image_preview); String[] titles = {"怀师", "南怀瑾军校", "闭关", "南怀瑾", "南公庄严照", "怀师法相"}; final int[] ids = {R.drawable.nanhuaijin_miss, R.drawable.nanhuaijin_school, R.drawable.nanhuaijin_biguan, R.drawable.nanhuaijin, R.drawable.nanhuaijin_zhuangyan, R.drawable.nanhuaijin_faxiang}; hListViewAdapter = new HorizontalListViewAdapter(getApplicationContext(),titles,ids); hListView.setAdapter(hListViewAdapter); // hListView.setOnItemSelectedListener(new OnItemSelectedListener() { // // @Override // public void onItemSelected(AdapterView
HorizontalListView.java 这就是自定义的横向listview
[java]
view plaincopyprint?package org.yanzi.ui; /* * HorizontalListView.java v1.5 * * * The MIT License * Copyright (c) 2011 Paul Soucy (paul@dev-smart.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ import java.util.LinkedList; import java.util.Queue; import android.content.Context; import android.database.DataSetObserver; import android.graphics.Rect; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ListAdapter; import android.widget.Scroller; public class HorizontalListView extends AdapterView
HorizontalListViewAdapter.java 横向listview的适配器,我将他单独写到一个java文件里。
[java]
view plaincopyprint?package org.yanzi.ui; import org.yanzi.testhorizontallistview.R; import org.yanzi.util.BitmapUtil; import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.media.ThumbnailUtils; 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 HorizontalListViewAdapter extends BaseAdapter{ private int[] mIconIDs; private String[] mTitles; private Context mContext; private LayoutInflater mInflater; Bitmap iconBitmap; private int selectIndex = -1; public HorizontalListViewAdapter(Context context, String[] titles, int[] ids){ this.mContext = context; this.mIconIDs = ids; this.mTitles = titles; mInflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//LayoutInflater.from(mContext); } @Override public int getCount() { return mIconIDs.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.horizontal_list_item, null); holder.mImage=(ImageView)convertView.findViewById(R.id.img_list_item); holder.mTitle=(TextView)convertView.findViewById(R.id.text_list_item); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } if(position == selectIndex){ convertView.setSelected(true); }else{ convertView.setSelected(false); } holder.mTitle.setText(mTitles[position]); iconBitmap = getPropThumnail(mIconIDs[position]); holder.mImage.setImageBitmap(iconBitmap); return convertView; } private static class ViewHolder { private TextView mTitle ; private ImageView mImage; } private Bitmap getPropThumnail(int id){ Drawable d = mContext.getResources().getDrawable(id); Bitmap b = BitmapUtil.drawableToBitmap(d); // Bitmap bb = BitmapUtil.getRoundedCornerBitmap(b, 100); int w = mContext.getResources().getDimensionPixelOffset(R.dimen.thumnail_default_width); int h = mContext.getResources().getDimensionPixelSize(R.dimen.thumnail_default_height); Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(b, w, h); return thumBitmap; } public void setSelectIndex(int i){ selectIndex = i; } }
下图是一个item被选定后,另一个item获得了焦点:
要点如下:
1、可以说这个HorizontalListView是完美的,但美中不足的并不是其他人说的不能点击、晃动、加载不全的问题,而是这个横向Listview的高度,如果你设成wrap_cotent那么将会占据整个屏幕,即使你将它适配器里的view的高度限制死,限制成很小,这个HorizontalListView的高度依然是全屏。本文代码里,我把图片缩略图弄成100dip,所以把这个HorizontalListView的高度设为了150dip。
2、在适配器里,我填充了一个图片,下面是文字。为了能让浏览图片时item有反应,搞了一个selector,它的用法详见这里.
但一开始在点击时完全没有反应。