处理ScrollView和ListView,GridView之间的冲突,

最好的办法就是继承这两个类,重写他们的onMeasure方法即可:

ListView:

import android.widget.ListView;

/**
* ScrollView中嵌入ListView,让ListView全显示出来
* @author John
*
*/
public class MyListView extends ListView{ public MyListView(android.content.Context context,android.util.AttributeSet attrs){
super(context, attrs);
} /**
* 设置不滚动
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec); } }

GridView:

import android.widget.GridView;

public class MyGridView extends GridView {
public MyGridView(android.content.Context context,
android.util.AttributeSet attrs) {
super(context, attrs);
} /**
* 设置不滚动
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec); } }

如果是ListView中嵌套GridView也可以用这个办法。简单实用的处理了这个冲突。

下面是重写ScrollView,实现有弹性的ScrollView

/**
* 有弹性的ScrollView
* 实现下拉弹回和上拉弹回
* @author John
*/
public class OwnScroview extends ScrollView { private static final String TAG = "ElasticScrollView"; //移动因子, 是一个百分比, 比如手指移动了100px, 那么View就只移动20px
//目的是达到一个延迟的效果
private static final float MOVE_FACTOR = 0.4f; //松开手指后, 界面回到正常位置需要的动画时间
private static final int ANIM_TIME = 300; //ScrollView的子View, 也是ScrollView的唯一一个子View
private View contentView; //手指按下时的Y值, 用于在移动时计算移动距离
//如果按下时不能上拉和下拉, 会在手指移动时更新为当前手指的Y值
private float startY; //用于记录正常的布局位置
private Rect originalRect = new Rect(); //手指按下时记录是否可以继续下拉
private boolean canPullDown = false; //手指按下时记录是否可以继续上拉
private boolean canPullUp = false; //在手指滑动的过程中记录是否移动了布局
private boolean isMoved = false; public OwnScroview(Context context) {
super(context);
} public OwnScroview(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
contentView = getChildAt(0);
}
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b); if(contentView == null) return; //ScrollView中的唯一子控件的位置信息, 这个位置信息在整个控件的生命周期中保持不变
originalRect.set(contentView.getLeft(), contentView.getTop(), contentView
.getRight(), contentView.getBottom());
} /**
* 在触摸事件中, 处理上拉和下拉的逻辑
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) { if (contentView == null) {
return super.dispatchTouchEvent(ev);
} int action = ev.getAction(); switch (action) {
case MotionEvent.ACTION_DOWN: //判断是否可以上拉和下拉
canPullDown = isCanPullDown();
canPullUp = isCanPullUp(); //记录按下时的Y值
startY = ev.getY();
break; case MotionEvent.ACTION_UP: if(!isMoved) break; //如果没有移动布局, 则跳过执行 // 开启动画
TranslateAnimation anim = new TranslateAnimation(0, 0, contentView.getTop(),
originalRect.top);
anim.setDuration(ANIM_TIME); contentView.startAnimation(anim); // 设置回到正常的布局位置
contentView.layout(originalRect.left, originalRect.top,
originalRect.right, originalRect.bottom); //将标志位设回false
canPullDown = false;
canPullUp = false;
isMoved = false; break;
case MotionEvent.ACTION_MOVE: //在移动的过程中, 既没有滚动到可以上拉的程度, 也没有滚动到可以下拉的程度
if(!canPullDown && !canPullUp) {
startY = ev.getY();
canPullDown = isCanPullDown();
canPullUp = isCanPullUp(); break;
} //计算手指移动的距离
float nowY = ev.getY();
int deltaY = (int) (nowY - startY); //是否应该移动布局
boolean shouldMove =
(canPullDown && deltaY > 0) //可以下拉, 并且手指向下移动
|| (canPullUp && deltaY< 0) //可以上拉, 并且手指向上移动
|| (canPullUp && canPullDown); //既可以上拉也可以下拉(这种情况出现在ScrollView包裹的控件比ScrollView还小) if(shouldMove){
//计算偏移量
int offset = (int)(deltaY * MOVE_FACTOR); //随着手指的移动而移动布局
contentView.layout(originalRect.left, originalRect.top + offset,
originalRect.right, originalRect.bottom + offset); isMoved = true; //记录移动了布局
} break;
default:
break;
} return super.dispatchTouchEvent(ev);
} /**
* 判断是否滚动到顶部
*/
private boolean isCanPullDown() {
return getScrollY() == 0 ||
contentView.getHeight() < getHeight() + getScrollY();
} /**
* 判断是否滚动到底部
*/
private boolean isCanPullUp() {
return contentView.getHeight() <= getHeight() + getScrollY();
} }

然后再xml中用上就行了。

android 有弹性的ScrollView 简单实现,与处理ScrollView和ListView,GridView之间的冲突的更多相关文章

  1. ScrollView listView gridView 之间的冲突问题

    在ScrollView中的listView gridView添加适配器之后添加//设置gridView整体的高度 public void setListViewHeightBasedOnChildre ...

  2. android scrollview 简单的使用

    以前写的Scrollview ,通常都是与Listview结合使用,不过因复杂可能新手不太懂,网上有许多文章,这里就不贴那个了DEMO了.  写了个简单的供大家参考:这样比较好理解(需要复杂的可以Q我 ...

  3. Android ScrollView嵌套HorizontalScrollView 滑动问题 ScrollView包括GridView显示问题

    今天项目使用到ScrollView嵌套HorizontalScrollView,ScrollView里包括GridView,发现几个问题非常经典.在此记录: 问题1.ScrollView嵌套Horiz ...

  4. Xamarin.Android之引导页的简单制作

    0x01 前言 对于现在大部分的APP,第一次打开刚安装或更新安装的APP都会有几个引导界面,通常这几个引导页是告诉用户 APP有些什么功能或者修改了什么bug.新增了什么功能等等等. 下面就用Xam ...

  5. Android Activity的生命周期简单总结

    Android Activity的生命周期简单总结 这里的内容参考官方的文档,这篇文章的目的不是去总结Activity是如何启动,如何创造,以及暂停和销毁的,而是从实际开发中分析在Activity各个 ...

  6. Android 设计随便说说之简单实践(合理组合)

    上一篇(Android 设计随便说说之简单实践(模块划分))例举了应用商店设计来说明怎么做模块划分.模块划分主要依赖于第一是业务需求,具体是怎么样的业务.应用商店则包括两个业务,就是向用户展示appl ...

  7. 怎样在Android实现桌面清理内存简单Widget小控件

    怎样在Android实现桌面清理内存简单Widget小控件 我们常常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...

  8. Android BLE与终端通信(一)——Android Bluetooth基础API以及简单使用获取本地蓝牙名称地址

    Android BLE与终端通信(一)--Android Bluetooth基础API以及简单使用获取本地蓝牙名称地址 Hello,工作需要,也必须开始向BLE方向学习了,公司的核心技术就是BLE终端 ...

  9. Android peferenceActivity 自己定义标题简单方法

    Android peferenceActivity 自己定义标题简单方法 peferenceActivity 全然使用定义好的布局. 因此不能简单象其他好窗体进行自定,如今我们须要加 一个自己定义标题 ...

随机推荐

  1. php : Warning: strftime(): It is not safe to rely on the system's timezone settings.

    使用 Smarty 的时候出现这种警告: Warning: strftime(): It is not safe to rely on the system's timezone settings. ...

  2. 绝对炫的3D幻灯片-SLICEBOX

    绝对炫的3D幻灯片-SLICEBOX http://www.jq22.com/jquery-info31

  3. display inline-block 垂直居中

    table td:after {display:inline-block;width:0;height:100%;vertical-align:middle;content:'';}

  4. Ubuntu下安装Koala

    1.下载koala ,官方网址 目前官方链接的到百度云上的包好像有问题,不能安装,这里分享下 https://yunpan.cn/ckAF4L3TR4kKG (提取码:179a) 2.执行 $ sud ...

  5. iOS - AppStores App 上架

    前言 1.准备 开发者账号 完工的项目 2.上架步骤 1) 创建 App ID 2) 创建证书请求文件(CSR文件) 3) 创建发布证书(CER) 4) 创建 Provisioning Profile ...

  6. static 作用

    静态,定义静态变量或者静态函数的时候使用该关键字. 被定义为static的函数,可以不需要new一个新类别而直接调用 比如Math类里有一个,public static sub()方法,那么你可以直接 ...

  7. Python_Day11_同步IO和异步IO

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...

  8. jQuery 日常工作集中问题

    1.siblings()方法:获得匹配元素中每个元素的同胞(除了自己外的其他同级元素) 导航栏选择效果 点击“华东地区”,其他同级元素灰色背景以及下拉菜单消失,当前元素有灰色背景以及下拉菜单.再次点击 ...

  9. (转)px、em、rem的区别和使用

    国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem(国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位),那么三者有什么区别,又各自有什么优劣呢? 一.px特点 1. IE ...

  10. 一道Integer面试题引发的对Integer的探究

    面试题: //在jdk1.5的环境下,有如下4条语句: Integer i01 = 59; int i02 = 59; Integer i03 =Integer.valueOf(59); Intege ...