处理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. TensorFlow支持windows了

    (留坑)找个时间测试一下. 终于来了,TensorFlow 新增官方 Windows 支持

  2. 区分debug和release生成文件的名称

    通常我们编译工程按照debug和release区分,且明确在Debug版本的生成文件中加入d标记.譬如: HelloWorld.exe 一般是release的生成文件,而debug版叫:HelloWo ...

  3. Sa yo na ra

    总想记点些什么. 都快忘了当初是为什么来到这里呢... 2014年10月,友人给我介绍了一门编程竞赛ACM,并给我演示了一下A+B.于是我知道了ACM的含义. 2014年12月,开始水入门题. 201 ...

  4. MFC编程入门之二十四(常用控件:列表框控件ListBox)

    前面两节讲了比较常用的按钮控件,并通过按钮控件实例说明了具体用法.本文要讲的是列表框控件(ListBox)及其使用实例. 列表框控件简介 列表框给出了一个选项清单,允许用户从中进行单项或多项选择,被选 ...

  5. SQL Tuning / SQL 性能 优化 调优

    Some key concents regarding SQL optimization predicate selectivity (column unique ratio) / cardinali ...

  6. onInterceptTouchEvent / onTouchEvent响应事件的详析

    onInterceptTouchEvent(),onTouchEvent() 默认返回false 注:事件分发机制是由 dispatchTouchEvent() 开始分发的 onInterceptTo ...

  7. 在eclipse中用gradle搭建MapReduce项目

    我用的系统是ubuntu14.04新建一个Java Project. 这里用的是gradle打包,gradle默认找src/main/java下的类编译.src目录已经有了,手动在src下创建main ...

  8. phpstorm使用手册

    参考:http://www.cnblogs.com/luojianqun/p/4596052.html 罗总说这是php最好的IDE,phpstorm9.02,没有之一.各种功能各种好,罗总此等大神说 ...

  9. Linux文件权限查看及修改命令chmod

    查看权限 Linux文件访问权限分为可读,可写和可执行三种. 可用ls -l命令查看,例: ls -l或者 ll 显示为 -r--r--r--. 1 root root 21 Jan 5 23:02 ...

  10. MySQL之存储引擎MyISAM/InnoDB高并发优化经验

    https://www.centos.bz/2011/09/mysql-myisam-innodb-optimization-experience/