ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
2015-04-21 18:09
701 查看
Google是不推荐在ScrollView 中放入一个可滚动的菜单的,比如放置一个ListView、GridView、ViewPager这些控件的,尽量不要让两者嵌套,但有时候还是有这个需求,先不管它合不合理。如果直接在ScrollView中嵌套只会出现一行,然后在其中滚动,这样不是很好,下面是我的整理,希望对大家有帮助,我也是从网上摘抄的,当然加入了一些我自己的东西。
一、在ScrollView中嵌套ListView,有两张方法
第一种是自定义View,继承ListView代码如下:
第二种在setAdapter之后调用Utility.setListViewHeightBasedOnChildren(listview)这个方法,有些资料说只能item的根布局要LinearLayout,但是我的跟布局为RelativeLayout也可以的。
这两种都可以,但是在有些情况下中能用第一种,比如你显示ListView是一个ListFragment就只能用第二种方法了。
二、在ScrollView中嵌套GridView
第一种自定义ScrollView
一、在ScrollView中嵌套ListView,有两张方法
第一种是自定义View,继承ListView代码如下:
import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; public class MyListView extends ListView { public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }第二种
import android.view.View; import android.view.ViewGroup; import android.widget.ListAdapter; import android.widget.ListView; public class Utility { public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); } }
第二种在setAdapter之后调用Utility.setListViewHeightBasedOnChildren(listview)这个方法,有些资料说只能item的根布局要LinearLayout,但是我的跟布局为RelativeLayout也可以的。
这两种都可以,但是在有些情况下中能用第一种,比如你显示ListView是一个ListFragment就只能用第二种方法了。
二、在ScrollView中嵌套GridView
import android.content.Context; import android.util.AttributeSet; import android.widget.GridView; public class NoScrollGridView extends GridView { public NoScrollGridView(Context context) { super(context); } public NoScrollGridView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }二、在ScrollView中嵌套ViewPager,也有两张方法
第一种自定义ScrollView
import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /** * 能够兼容ViewPager的ScrollView * * @Description: 解决了ViewPager在ScrollView中的滑动反弹问题 */ public class ScrollViewExtend extends ScrollView { // 滑动距离及坐标 private float xDistance, yDistance, xLast, yLast; public ScrollViewExtend(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f; xLast = ev.getX(); yLast = ev.getY(); break; case MotionEvent.ACTION_MOVE: final float curX = ev.getX(); final float curY = ev.getY(); xDistance += Math.abs(curX - xLast); yDistance += Math.abs(curY - yLast); xLast = curX; yLast = curY; if (xDistance > yDistance) { return false; } } return super.onInterceptTouchEvent(ev); } }第二种是自定义ViewPager
import android.content.Context; import android.graphics.PointF; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; /** * 嵌套在ScrollView中的ViewPager,解决冲突 * @author m3 * */ public class ChildViewPager extends ViewPager { /** 触摸时按下的点 **/ PointF downP = new PointF(); /** 触摸时当前的点 **/ PointF curP = new PointF(); OnSingleTouchListener onSingleTouchListener; public ChildViewPager(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public ChildViewPager(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { // TODO Auto-generated method stub // 当拦截触摸事件到达此位置的时候,返回true, // 说明将onTouch拦截在此控件,进而执行此控件的onTouchEvent return true; } @Override public boolean onTouchEvent(MotionEvent arg0) { // TODO Auto-generated method stub // 每次进行onTouch事件都记录当前的按下的坐标 curP.x = arg0.getX(); curP.y = arg0.getY(); if (arg0.getAction() == MotionEvent.ACTION_DOWN) { // 记录按下时候的坐标 // 切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变 downP.x = arg0.getX(); downP.y = arg0.getY(); // 此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); } if (arg0.getAction() == MotionEvent.ACTION_MOVE) { // 此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); } if (arg0.getAction() == MotionEvent.ACTION_UP) { // 在up时判断是否按下和松手的坐标为一个点 // 如果是一个点,将执行点击事件,这是我自己写的点击事件,而不是onclick if (downP.x == curP.x && downP.y == curP.y) { onSingleTouch(); return true; } } return super.onTouchEvent(arg0); } /** * 单击 */ public void onSingleTouch() { if (onSingleTouchListener != null) { onSingleTouchListener.onSingleTouch(); } } /** * 创建点击事件接口 * * @author wanpg * */ public interface OnSingleTouchListener { public void onSingleTouch(); } public void setOnSingleTouchListener( OnSingleTouchListener onSingleTouchListener) { this.onSingleTouchListener = onSingleTouchListener; } }第二个问题在ScrollView嵌套ListView,GridView,如果这些子控件很长超出了屏幕的高度,那么ScrollView会自动滚到底部,但是我们需要默认在顶部,我们要在ListView和GridView上面的view中加入,一下代码即可解决:
view.setFocusable(true); view.setFocusableInTouchMode(true); view.requestFocus();这段代码在初始化的时候就让该界面的顶部的某一个控件获得焦点,滚动条自然就显示到顶部了,顺便附一下我找到答案的地方http://blog.csdn.net/studyalllife/article/details/42970975这上面写的很混乱,大家可以参考一下,大功告成。
相关文章推荐
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- 解决ScrollView中嵌套ListView或GridView导致的ScrollView自动滚动到ListView或GridView位置的问题
- android listview嵌套viewpager,viewpager嵌套gridview,解决内嵌无法显示以及时间冲突的问题
- 修改Scrollview嵌套其他可滚动控件 如listview或者recycleView等自动滚动的问题
- Scrollview嵌套Listview、GridView、RecycleView时只能显示一行或者自动滚动到底部
- ScrollView嵌套ListView,GridView,RecyclerView以及RecyclerView嵌套RecyclerView显示不全的解决方法
- Android ScrollView嵌套Viewpager嵌套ListView切换时到顶部或位置改变问题解决
- 解决ScrollView嵌套viewPager中嵌套listView滑动事件冲突问题(水平方向)
- ScrollView嵌套GridView,ListView自动滚动到第一条Item的解决办法
- Android在ScrollView中嵌套ViewPager以及ListView的可能出现的问题以及解决方案
- 解决ScrollView嵌套ListView,GridView,ViewPager
- 解决ScrollView嵌套ListView,ListView填充容器后,界面自动滚动回顶部的问题
- Android ViewPager和ScrollView嵌套滚动问题解决方案
- ScrollView嵌套ViewPager结构,在ViewPager翻页会导致ScrollView自动滑到底部的问题。
- 解决ScrollView 嵌套 ListView GridView显示不全,以及默认不在ScrollView顶部的问题