--在开发类似新闻功能的App过程中需要在新闻页面展示新闻附件,附件一多的话一行展示不完,换行又不好看,为此需要做像今日头条导航栏那样可以横向滑动的列表,不同点在于附件数量是动态添加的 可能有一个 也可能是十个,所以做成ListView方式最好。下面是网上横向ListView的例子,很好用,拿来借鉴一下:

public class HorizontalListView extends AdapterView<ListAdapter> {
public boolean mAlwaysOverrideTouch = true;
protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;public HorizontalListView(Context context, AttributeSet attrs) {super(context, attrs);initView();
}private synchronized void initView() {mLeftViewIndex = -1;mRightViewIndex = 0;mDisplayOffset = 0;mCurrentX = 0;mNextX = 0;mMaxX = Integer.MAX_VALUE;mScroller = new Scroller(getContext());mGesture = new GestureDetector(getContext(), mOnGesture);
}@Override
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {mOnItemSelected = listener;
}@Override
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {mOnItemClicked = listener;
}@Override
public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) {mOnItemLongClicked = listener;
}private DataSetObserver mDataObserver = new DataSetObserver() {@Overridepublic void onChanged() {synchronized (HorizontalListView.this) {mDataChanged = true;}invalidate();requestLayout();}@Overridepublic void onInvalidated() {reset();invalidate();requestLayout();}};@Override
public ListAdapter getAdapter() {return mAdapter;
}@Override
public View getSelectedView() {//TODO: implementreturn null;
}@Override
public void setAdapter(ListAdapter adapter) {if (mAdapter != null) {mAdapter.unregisterDataSetObserver(mDataObserver);}mAdapter = adapter;mAdapter.registerDataSetObserver(mDataObserver);reset();
}private synchronized void reset() {initView();removeAllViewsInLayout();requestLayout();
}@Override
public void setSelection(int position) {//TODO: implement
}private void addAndMeasureChild(final View child, int viewPos) {LayoutParams params = child.getLayoutParams();if (params == null) {params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);}addViewInLayout(child, viewPos, params, true);child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
}@Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);if (mAdapter == null) {return;}if (mDataChanged) {int oldCurrentX = mCurrentX;initView();removeAllViewsInLayout();mNextX = oldCurrentX;mDataChanged = false;}if (mScroller.computeScrollOffset()) {int scrollx = mScroller.getCurrX();mNextX = scrollx;}if (mNextX <= 0) {mNextX = 0;mScroller.forceFinished(true);}if (mNextX >= mMaxX) {mNextX = mMaxX;mScroller.forceFinished(true);}int dx = mCurrentX - mNextX;removeNonVisibleItems(dx);fillList(dx);positionItems(dx);mCurrentX = mNextX;if (!mScroller.isFinished()) {post(new Runnable() {@Overridepublic void run() {requestLayout();}});}
}private void fillList(final int dx) {int edge = 0;View child = getChildAt(getChildCount() - 1);if (child != null) {edge = child.getRight();}fillListRight(edge, dx);edge = 0;child = getChildAt(0);if (child != null) {edge = child.getLeft();}fillListLeft(edge, dx);}private void fillListRight(int rightEdge, final int dx) {while (rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);addAndMeasureChild(child, -1);rightEdge += child.getMeasuredWidth();if (mRightViewIndex == mAdapter.getCount() - 1) {mMaxX = mCurrentX + rightEdge - getWidth();}if (mMaxX < 0) {mMaxX = 0;}mRightViewIndex++;}}private void fillListLeft(int leftEdge, final int dx) {while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);addAndMeasureChild(child, 0);leftEdge -= child.getMeasuredWidth();mLeftViewIndex--;mDisplayOffset -= child.getMeasuredWidth();}
}private void removeNonVisibleItems(final int dx) {View child = getChildAt(0);while (child != null && child.getRight() + dx <= 0) {mDisplayOffset += child.getMeasuredWidth();mRemovedViewQueue.offer(child);removeViewInLayout(child);mLeftViewIndex++;child = getChildAt(0);}child = getChildAt(getChildCount() - 1);while (child != null && child.getLeft() + dx >= getWidth()) {mRemovedViewQueue.offer(child);removeViewInLayout(child);mRightViewIndex--;child = getChildAt(getChildCount() - 1);}
}private void positionItems(final int dx) {if (getChildCount() > 0) {mDisplayOffset += dx;int left = mDisplayOffset;for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);int childWidth = child.getMeasuredWidth();child.layout(left, 0, left + childWidth, child.getMeasuredHeight());left += childWidth + child.getPaddingRight();}}
}public synchronized void scrollTo(int x) {mScroller.startScroll(mNextX, 0, x - mNextX, 0);requestLayout();
}@Override
public boolean dispatchTouchEvent(MotionEvent ev) {boolean handled = super.dispatchTouchEvent(ev);handled |= mGesture.onTouchEvent(ev);return handled;
}protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {synchronized (HorizontalListView.this) {mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);}requestLayout();return true;
}protected boolean onDown(MotionEvent e) {mScroller.forceFinished(true);return true;
}private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {return HorizontalListView.this.onDown(e);}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {synchronized (HorizontalListView.this) {mNextX += (int) distanceX;}requestLayout();return true;}@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);if (isEventWithinView(e, child)) {if (mOnItemClicked != null) {mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));}if (mOnItemSelected != null) {mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));}break;}}return true;}@Overridepublic void onLongPress(MotionEvent e) {int childCount = getChildCount();for (int i = 0; i < childCount; i++) {View child = getChildAt(i);if (isEventWithinView(e, child)) {if (mOnItemLongClicked != null) {mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));}break;}}}private boolean isEventWithinView(MotionEvent e, View child) {Rect viewRect = new Rect();int[] childPosition = new int[2];child.getLocationOnScreen(childPosition);int left = childPosition[0];int right = left + child.getWidth();int top = childPosition[1];int bottom = top + child.getHeight();viewRect.set(left, top, right, bottom);return viewRect.contains((int) e.getRawX(), (int) e.getRawY());}
};
}
复制代码

--界面引用如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dddd"
android:gravity="center_horizontal"
android:orientation="vertical"><com.hundsun.gildata.downloadpdf.HorizontalListViewandroid:id="@+id/list"android:layout_width="match_parent"android:layout_height="40dp"/>
</LinearLayout>
复制代码

--适配器

public class HorizontalListViewAdapter extends BaseAdapter {
List<String> mData;
Context mContext;
public HorizontalListViewAdapter(Context mContext, List<String> mData) {this.mData = mData;this.mContext=mContext;
}@Override
public int getCount() {return mData.size();
}@Override
public Object getItem(int position) {return position;
}private ViewHolder vh = new ViewHolder();private static class ViewHolder {private TextView file;
}@Override
public long getItemId(int position) {return position;
}@Override
public View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.hor_list_item, null);vh.file = (TextView) convertView.findViewById(R.id.file);convertView.setTag(vh);} else {vh = (ViewHolder) convertView.getTag();}return convertView;
}
}
复制代码

--适配器很简单,只需要一个TextView就行了,自定义是为了给他添加附件类型图标。 适配器用到的hor_list_item.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@xml/attch"android:gravity="center"android:layout_margin="4dp"android:orientation="horizontal"android:padding="4dp"><TextViewandroid:id="@+id/file"android:layout_width="match_parent"android:layout_height="match_parent"android:drawableLeft="@drawable/file"android:drawableStart="@drawable/file"android:gravity="center"android:focusable="false"android:padding="4dp"android:text="附件"android:textColor="#6f6f6f"/></LinearLayout>
复制代码

--在MainActivity中可以这么用:

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
HorizontalListView mHorizontalListView;
HorizontalListViewAdapter mAdapter;
List<String> mData;@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mHorizontalListView = (HorizontalListView) findViewById(R.id.list);initView();
}
private void initView() {mData = new ArrayList<>();mData.add("504540");mData.add("457662");mData.add("502690");mData.add("457669");mData.add("457672");mData.add("481660");mData.add("479358");mAdapter = new HorizontalListViewAdapter(this, mData);mHorizontalListView.setAdapter(mAdapter);mHorizontalListView.setOnItemClickListener(this);mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);WifiInfo wifiInfo = mWifiManager.getConnectionInfo();editPort.setText(int2ip(wifiInfo.getIpAddress()) + ":55555");
}
@Override
public void onItemClick(AdapterView<?> view, View view1, final int i, long l) {Toast.makeText(this, "id=" + mData.get(i), Toast.LENGTH_SHORT).show();
}
}
复制代码

转载于:https://juejin.im/post/5a31dc4b6fb9a0451f30f332

Android横向ListView功能实现相关推荐

  1. android 横向listview左右滑动,实现可以横向滑动的Listview

    其实做法很简单就是在你的listview的外部加一个HorizontalScrollView就行了 main.xml如下 xmlns:tools="http://schemas.androi ...

  2. 【Android】Listview返回顶部,快速返回顶部的功能实现,详解代码。

    2019独角兽企业重金招聘Python工程师标准>>> 作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://we ...

  3. Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/12684155 前段时间因为换工作的缘故又恰巧碰到国庆节,所以有段时间自己没有更新博客了 ...

  4. android 全选功能,Android实现ListView控件的多选和全选功能实例

    本文实例讲述了Android实现ListView控件的多选和全选功能.分享给大家供大家参考,具体如下: 主程序代码 MainActivity.Java package yy.test; import ...

  5. Android实现ListView的A-Z字母排序和过滤搜索功能

    原文地址: http://blog.csdn.net/xiaanming/article/details/12684155 首先先看下效果图   上面是一个带删除按钮的EditText,我们在输入框中 ...

  6. Android实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/12684155 前段时间因为换工作的缘故又恰巧碰到国庆节,所以有段时间自己没有更新博客了 ...

  7. android 字母排序i,Android 使用ListView的A-Z字母排序功能实现联系人模块

    在上一篇文章当中,主要学习了ListView的A-Z字母排序功能以及根据输入框的输入值改变来过滤搜索结果,如果输入框里面的值为空,更新为原来的列表,否则为过滤数据列表,包括汉字转成拼音的功能,如果你还 ...

  8. android列表字母排序,Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音...

    [实例简介]Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音 [实例截图] [核心代码] package com.example.sortlistview; imp ...

  9. android仿qq动态视频播放,Android 自定义ListView实现QQ空间界面(说说内包含图片、视频、点赞、评论、转发功能)...

    前端时间刚好需要做一个类似于QQ空间的社区分享功能,说说内容包含文字(话题.内容).视频.图片,还需包含点赞,评论,位置信息等功能. 就采用LIstview做了一个,先来看下效果,GIF太大,CSDN ...

最新文章

  1. SpringMVC项目前台利用ajaxFileUpload传递图片后台接收
  2. HTML坦克大战学习02---坦克动起来
  3. Hyperledger Fabric 私有数据(3)交易流程
  4. mysql.user表中Host为%的含义
  5. 背包问题 codevs2210 数字组合
  6. Docker安装与修改默认工作目录
  7. 网络流24题 洛谷 2763 试题库问题
  8. C++构造函数、new、delete
  9. SharePoint 2013 创建web应用程序报错This page can’t be displayed
  10. 借助Haproxy_exporter实现对MarathonLb的流量和负载实例业务的可用状态监控
  11. jdbc连接数据库以及crud(简单易懂,本人亲测可用 有源代码和数据库)
  12. http的rest服务简介_REST概念简介
  13. java 邮件批量发送邮件_利用Java实现电子邮件的批量发送[转载]
  14. Android 使用listview实现树形结构
  15. [转]scite文本编辑器的说明
  16. 狂飙高启兰好飒,你看狂飙了吗?
  17. 在我们这个地方,你必须不停地奔跑,才能留在原地
  18. Activity跳转后自动执行了onDestroy
  19. reverse()和reverse_copy()用法
  20. 第四章:磁盘和SSD基础知识(提供原稿)

热门文章

  1. Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊...
  2. zend studio 9实用快捷键大全 分享ZEND STUDIO 9的常用快捷键,高亮显示相同变量。...
  3. Linux批量部署 EXPECT 使用
  4. Linux下怎么创建和进入带有空格的文件夹
  5. 云计算相关资料/博客/网上收集的关于OpenStack的一些资源
  6. Codeforces.1110E.Magic Stones(思路 差分)
  7. ubuntu无法获得锁 /var/lib/dpkg -open 问题
  8. What are Unix swap (.swp) files?
  9. 【2】thinkphp 3.2.3简单介绍
  10. SQL Server中drop、truncate和delete语句的用法