HorzontallListview与scrollview冲突解决
来源:互联网 发布:笔记本能开淘宝店铺 编辑:程序博客网 时间:2024/06/11 06:01
自定义HorzontallListview:
HorizontalListView.java
package com.liucanwen.horizontallistview.view;
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.View.MeasureSpec;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
/**
* 重写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()
{
@Override
public void onChanged()
{
synchronized (HorizontalListView.this)
{
mDataChanged = true;
}
invalidate();
requestLayout();
}
@Override
public void onInvalidated()
{
reset();
invalidate();
requestLayout();
}
};
@Override
public ListAdapter getAdapter()
{
return mAdapter;
}
@Override
public View getSelectedView()
{
// TODO: implement
return 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()
{
@Override
public 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()
{
@Override
public boolean onDown(MotionEvent e)
{
return HorizontalListView.this.onDown(e);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY)
{
return HorizontalListView.this
.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
synchronized (HorizontalListView.this)
{
mNextX += (int) distanceX;
}
requestLayout();
return true;
}
@Override
public 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;
}
@Override
public 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());
}
};
}
自定义Scrollview
MyScrollView.java
package com.liucanwen.horizontallistview.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
/**
* 重写ScrollView,以解决ScrollView与水平listView滑动时冲突
*/
public class MyScrollView extends ScrollView
{
private GestureDetector mGestureDetector;
View.OnTouchListener mGestureListener;
public MyScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
mGestureDetector = new GestureDetector(new YScrollDetector());
setFadingEdgeLength(0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
return super.onInterceptTouchEvent(ev)
&& mGestureDetector.onTouchEvent(ev);
}
class YScrollDetector extends SimpleOnGestureListener
{
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
if (Math.abs(distanceY) > Math.abs(distanceX))
{
return true;
}
return false;
}
}
}
MainActivity.java
package com.liucanwen.horizontallistview;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.liucanwen.horizontallistview.view.HorizontalListView;
public class MainActivity extends Activity
{
private HorizontalListView listview;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeViews();
}
private void initializeViews()
{
listview = (HorizontalListView) findViewById(R.id.listview);
listview.setAdapter(new MyAdapter());
}
class MyAdapter extends BaseAdapter
{
@Override
public int getCount()
{
return 10;
}
@Override
public Object getItem(int position)
{
return null;
}
@Override
public long getItemId(int position)
{
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view = LayoutInflater.from(MainActivity.this).inflate(
R.layout.listview_item, null);
return view;
}
}
}
activity_main.xml
<RelativeLayout 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"
tools:context=".MainActivity" >
<com.liucanwen.horizontallistview.view.MyScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/listview_layout"
android:layout_width="fill_parent"
android:layout_height="180dip"
android:background="#ddd"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="5dip" >
<com.liucanwen.horizontallistview.view.HorizontalListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~只是点位超过一屏而已~"
android:textSize="20dip" />
</LinearLayout>
</com.liucanwen.horizontallistview.view.MyScrollView>
</RelativeLayout>
应该都看的懂了吧,可以直接拿去用的。
- HorzontallListview与scrollview冲突解决
- ScrollView与ListView冲突解决
- scrollView与ListView 冲突解决
- ScrollView与ListView冲突解决
- 解决ListView与ScrollView冲突
- scrollview与recycleview冲突解决
- Scrollview 与 listview 冲突解决?
- 解决scrollview与listview冲突问题
- 解决ScrollView 与viewpager 焦点冲突
- 解决ScrollView 与listview冲突问题
- 解决ScrollView 与viewpager 焦点冲突
- 解决viewflipper 与scrollview的手势冲突
- 解决ScrollView 与viewpager 焦点冲突
- scrollview与手势冲突如何解决
- scrollview与手势冲突如何解决
- ListView、GridView与ScrollView嵌套冲突解决
- 自定义MyListView,解决与ScrollView滑动冲突
- ScrollView与Listview滑动冲突解决
- #greendao#NoClassDefFoundError:
- Android Studio 使用小技巧和快捷键
- spring bean装配(bean的作用域、bean的生命周期、Aware接口、Bean的自动装配Autowiring、资源文件Resources )
- Android干货·收集站
- Java中ArrayList和LinkedList区别
- HorzontallListview与scrollview冲突解决
- log4net输出日志
- 【CC2640】CC2640无线MCU BLE-Stack™软件开发套件发行说明
- Java 8 特性 – 终极手册
- java关键字知识点总结
- Python Django进阶教程(二)(模版过滤器,标签)
- Oracle中REGEXP_SUBSTR函数的使用说明
- 看一遍就完全搞定的正则表达式教程
- 把请求的参数封装为xml