怎么理解View一旦有了设置view移出父布局局就不能添加到ListView中了?

Android实践之ScrollView中滑动冲突处理 - 简书
Android实践之ScrollView中滑动冲突处理
转载注明出处:
在Android开发中,如果是一些简单的布局,都很容易搞定,但是一旦涉及到复杂的页面,特别是为了兼容小屏手机而使用了ScrollView以后,就会出现很多点击事件的冲突,最经典的就是ScrollView中嵌套了ListView。我想大部分刚开始接触Android的同学们都踩到过这个坑,这一篇文章就从最近做的一个项目讲起,然后在过程中提供一些解决冲突的思路。
项目有一个页面,涉及到了ViewPager,MapView,ListView,也就是说在一个页面中,会有这三个View,很明显,屏幕无法完全显示,需要ScrollView来做一下支援,就引入了ScrollView作为外层的容器。但是由于这个页面的数据展示需要做到用户手动下拉刷新,于是又引入了官方的SwipeRefreshLayout。
于是这个页面的布局就成了这样子。如下图(细节布局忽略)。
布局图.png
加入了ScrollView和SwipeRefreshLayout之后引入了新的问题,就是各个控件之间的事件冲突,嵌套在ScrollView中的ViewPager、MapView、ListView都需要能够正确的处理点击事件,特别是ListView,需求要求它在ScrollView中可以滑动,两种滑动混淆在一起,不是特别好处理。
问题提出来了,下面直接看解决思路。
解决滑动冲突的思路
在ViewGroup中有个方法叫requestDisallowInterceptTouchEvent(boolean disallowIntercept),这个方法可以用来控制该ViewGroup是否截断点击事件。我们解决滑动冲突的时候,其实就是在某个时机去调用这个方法,让父布局不截断点击事件,将点击事件传递到子View,让相关的子View去处理。
下面就是关于在项目中处理各种点击事件冲突的一些例子和思考。处理的方法只是提供一种思路,可能并不是最优的方法,肯定存在其他思路的解决方案。
以下处理滑动冲突的方案都是在子View的OnTouchListener里面进行处理,并没有去复写控件的点击事件处理过程,在使用中还是比较方便的。
MapView地图页面滑动冲突
MapView与ScrollView的冲突主要在于,当用户点击到MapView地图并且滑动的时候,希望由地图Map去处理点击事件,并包括后续的滑动事件、双手指缩放地图等等。
在ScrollView中,是会默认截断点击事件的,导致用户点击到地图后,地图基本是没有反应,更别谈双手指缩放地图了。
用户手指点击到地图,并且滑动的时候,很难确定用户是要ScrollView上下滑动还是操控地图内容滑动,所以我简单的认为,只要用户手指点击到地图,就是要对地图进行操作;当用户手指抬起,就认为用户不需要操作地图了。
解决思路也很简单,就是在用户点击到地图或者滑动地图时候,让ScrollView不截断点击事件,并传递给子View处理,也就是地图去处理点击事件;当用户手指抬起的时候,将ScrollView的状态恢复至之前的状态,也就是ScrollView可以截断点击事件。
我使用的是百度地图,直接上代码,更容易理解。
mMapView.getChildAt(0).setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
//允许ScrollView截断点击事件,ScrollView可滑动
mScrollView.requestDisallowInterceptTouchEvent(false);
//不允许ScrollView截断点击事件,点击事件由子View处理
mScrollView.requestDisallowInterceptTouchEvent(true);
ViewPager滑动冲突解决
在这个项目中,ViewPager在页面最顶层,如果只是ScrollView里面嵌套了ViewPager,因为这两个控件是不同方向的滑动事件,所以基本不会出现冲突。
但是由于引入了SwipeRefreshLayout,我发现在滑动ViewPager的时候,很容易就触发了SwipeRefreshLayout的下来刷新,进而有可能阻断了ViewPager的左右滑动效果,体验很不好。而且在滑动ViewPager的过程中,用户滑动肯定不是一直水平的,会有一定程度向上向下的滑动。
ViewPager处理冲突和地图处理冲突有些不同,因为当用户点击到ViewPager,在滑动过程中,基本就可以猜测到用户是想左右滑动ViewPager还是上下滑动ScrollView(或者下拉刷新),这就不能像地图一样,在点击到ViewPager就禁止ScrollView截断点击事件(或者SwipeRefreshLayout下拉刷新功能),需要在滑动过程中做出判断。
解决思路就是,设定一个阈值,一旦用户在X轴也就是横向滑动距离超过这个阈值,我就认为用户是要左右滑动ViewPager,就禁止ScrollView截断点击事件同时设置SwipeRefreshLayout不能下拉刷新。当用户抬起手指,就认为用户对ViewPager的操作已经完毕,将ScrollView和SwipeRefreshLayout状态恢复。
mViewPager.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN) {
// 记录点击到ViewPager时候,手指的X坐标
mLastX = event.getX();
if(action == MotionEvent.ACTION_MOVE) {
// 超过阈值
if(Math.abs(event.getX() - mLastX) & 60f) {
mRefreshLayout.setEnabled(false);
mScrollView.requestDisallowInterceptTouchEvent(true);
if(action == MotionEvent.ACTION_UP) {
// 用户抬起手指,恢复父布局状态
mScrollView.requestDisallowInterceptTouchEvent(false);
mRefreshLayout.setEnabled(true);
用户点击到ViewPager时候,记录下点击位置的X坐标,当用户滑动过程中,如果在X轴上面的滑动超过阈值(我写的是60f,这个可以在实际使用中自行设置最佳的阈值),就禁止ScrollView截断点击事件,同时设置不可下拉刷新。当用户手指离开屏幕,将ScrollView和SwipeRefreshLayout的状态恢复。
ListView滑动冲突解决
在ScrollView中嵌套ListView,会出现各种各样奇怪的问题。比如说ListView显示有问题,可能才一两个Item那么高,并没有完全的展开。网上流传解决这种问题的方法会有两种。
根据展示数据的个数乘以每一个Item的高度,计算出ListView的总体高度,然后动态的设置ListView的高度
复写ListView的onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,让ListView完全展开
这两种方法都可以解决ListView展示不完全的问题,而且也可以滑动(其实是使用ScrollView的滑动效果),但是有一个最大的遗憾,就是ListView里面的View不能复用了。因为这两种方法都是算出了ListView的全部高度,然后将ListView控件的高度设置成这个高度,这样的话,ListView就相当于一个LinearLayout的布局了,失去了复用View的优势,而且在某些场景可能还没有LinearLayout好用,更甚的是,如果有大量图片的话,很容易就OOM了,这是在研发过程中最不希望看见的。
可以参考一下美团,美团的首页,就是一个ScrollView,下滑的时候会发现,并不能无限向下滑动,到了底部会提醒跳转到一个二级页面去查看全部的团购信息。这是处理ScrollView里面嵌套类似ListView列表布局的时候的一种解决方案。
但是在我遇见的这个项目里面,并不能这样处理。
上面的提到的两种解决思路很明确,如果想要ListView正常展示就需要确定ListView的高度,这个很重要。
所以首先,我需要在布局文件中设置ListView的高度,是一个明确的数值。设置高度之后,如果ListView中的数据的Item总高度超过ListView所设置的高度,就可以复用View了。但是这只是解决了ListView的显示问题,ListView与ScrollView的滑动冲突,并没有解决。
要解决滑动的冲突,最主要的是确定禁止ScrollView截断点击事件的时机,然后来分析有哪些时机。
ScrollView在未滑动到底部时候,如果点击并滑动ListView时候,ListView是不能滑动的,不禁止。
如果ScrollView滑动到底部,且ListView已经到顶部,继续下拉ListView,其实会拉动ScrollView,不禁止。
如果ScrollView滑动到底部,用户向上滑,ListView滑动,禁止ScrollView截断点击事件能力
很明显,在判断禁止ScrollView截断点击事件时机的时候,需要知道ScrollView是否滑动到了底部。于是,重写了ScrollView的ScrollChanged()方法,来判断ScrollView是否滑动到底部(SDK API 23版本中ScrollView可以设置setOnScrollChangeListener()来监听滑动的变化,但是之前版本不支持,为了兼容,自己需要重写)。
protected void onScrollChanged(int l, int t, int oldl, int oldt){
super.onScrollChanged(l,t,oldl,oldt);
// 滑动的距离加上本身的高度与子View的高度对比
if(t + getHeight() &=
getChildAt(0).getMeasuredHeight()){
// ScrollView滑动到底部
if(mOnScrollToBottomListener != null) {
mOnScrollToBottomListener.onScrollToBottom();
if(mOnScrollToBottomListener != null) {
mOnScrollToBottomListener.onNotScrollToBottom();
public void setScrollToBottomListener(OnScrollToBottomListener listener) {
this.mOnScrollToBottomListener =
public interface OnScrollToBottomListener {
void onScrollToBottom();
void onNotScrollToBottom();
有了思路,而且ScrollView滑动到底部的标识也可以拿到,下面就可以直接来解决滑动冲突了,直接看代码。
mScrollView.setScrollToBottomListener(new BottomScrollView.OnScrollToBottomListener() {
public void onScrollToBottom() {
isSvToBottom =
public void onNotScrollToBottom() {
isSvToBottom =
mListView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN) {
mLastY = event.getY();
if(action == MotionEvent.ACTION_MOVE) {
int top = mListView.getChildAt(0).getTop();
float nowY = event.getY();
if(!isSvToBottom) {
// 允许scrollview拦截点击事件, scrollView滑动
mScrollView.requestDisallowInterceptTouchEvent(false);
} else if(top == 0 && nowY - mLastY & THRESHOLD_Y_LIST_VIEW) {
// 允许scrollview拦截点击事件, scrollView滑动
mScrollView.requestDisallowInterceptTouchEvent(false);
// 不允许scrollview拦截点击事件, listView滑动
mScrollView.requestDisallowInterceptTouchEvent(true);
相对于其他的控件来说,ListView和ScrollView之间的滑动冲突更难解决,但其实在实际使用中并不推荐ScrollView里面嵌套ListView,一旦业务复杂,很容易出现各种UI和业务逻辑冲突的错误。
由于地图加入比较麻烦,所以在Demo中并没有引入地图。看一下运行效果。
本篇文章只是提供一种解决方法的思路,在具体的场景下,交互往往是贴合具体业务需求的。但是不管怎么样,找出点击事件截断和处理的时机是最重要的,围绕这个关键点,总能找出相应的解决方法。
附上Demo工程地址:
我总太想成为别人,而忘了自己。
如果有一天我还能跑,为什么要满足地待在原地呢?
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
拦截的艺术 先来看接口ViewParent中的一个函数 参数disallowIntercept的意思就是childView告诉父容器要不要进行拦截 true :告诉所有父控件不要拦截,事件交由childrenView处理 false:告诉所有父控件拦截。在父控件的onInt...
来源:https://github.com/Trinea/android-open-project 更多:Android 开源库获取途径整理 目前包括: Android 开源项目第一篇——个性化控件(View)篇 包括ListView、ActionBar、Menu、View...
内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新ViewPager图表(Chart)菜单(Menu)浮动菜单对话框空白页滑动删除手势操作RecyclerViewCardColorDrawableSpinner...
如今稍显沉寂的现金贷,在之前的短短几个月内,可谓大起大落。先是凭借其强劲的盈利能力受到各大资本的热捧,一时风头无两,然而随后便因其超高的利率及暴力催收等问题被媒体口诛笔伐。在监管整顿开始实施后,整个圈子仿佛也静了下来,但是不可否认的是现金贷对借贷人群的影响并没有消除。 在2...
脈乃血派 氣血之先 血之隧道 氣息應焉其象法地 血之府也 心之合也 皮之部也資始於腎 資生於胃 陽中之陰 本乎營衛營者陰血 衛者陽氣 營行脈中 衛行脈外脈不自行 隨氣而至 氣動脈應 陰陽之義氣如橐籥 血如波瀾 血脈氣息 上下循環十二經中 皆有動脈 惟手太陰 寸口取決此經屬肺...
“不喜欢我是你的事,喜不喜欢你是我的事,你可以让你喜欢我,但是你没有权利让我不喜欢你。” 第一次真正喜欢一个人的时候,是在去年的8月,算是夏天吧,他给她的第一印象,这人好幼稚,赶巧,沐白就喜欢幼稚的人,感觉和她有共同语言。 那个男生并没有小说里形容的那么好看,他只是普普通通...
1、Oracle 默认用户 sys(维护系统信息和管理实例) system(管理数据库用户、权限和存储) scott(示范用户) 2、修改Oracle用户名密码 修改密码三步曲 查看Oracle用户 select user name from db a_ 登录s...
总不自觉的在控制老公, 想不起来自己是个自由的人。 有什么比洗完澡,一个人思想的游荡更美好,更重要,永远想着控制别人,确一辈子不知道过了什么样的日子,后悔晚已。 为什么不让自己的思想变得无限可能,为什么不试试去突破自己的极限,而不是活在别人的眼里。他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)android中如何从view里关掉他的父Activity?
假如listview的item是一个布局文件,如果点击这个按钮之后跳转到另一个Activity中同时也要把listview所在的Activity关闭掉该如何去做。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 网友回复:
android中如何从view里关掉他的父Activity?
【android中如何从view里关掉他的父Activity?】
请将本文分享给你的朋友:
android中如何从view里关掉他的父Activity? 的相关文章
------分隔线----------------------------
北京联盟郑重声明:本文仅代表作者个人观点,与北京联盟无关。其原创性及文中陈述内容未经本站证实,北京联盟对本文及其中全部或者部分内容的真实性、完整性、及时性不作任何保证和承诺,请网友自行核实相关内容。android 通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果
看到了吗?就是这种效果:我再跟大家简单的叙述一下;
头部标题有三个:剧本梗概、剧本正文、剧本介绍。
当ScrollView滑到剧本中的无论哪一个内容标题的时候头部的大标题将被选中并呈现橙色;而三个标题内容下面是ListView的item,嵌在其父控件Scrollview中的。
下面让我们分析一下代码:
布局: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="wrap_content"
android:background="#f8f8f8"
android:gravity="top"
tools:context=".MainActivity" &
&LinearLayout
android:id="@+id/liLay_tabs"
android:layout_width="fill_parent"
android:layout_height="35dip"
android:background="#fff"
android:gravity="center_vertical"
android:orientation="horizontal" &
&LinearLayout
android:id="@+id/liLay_tabsLeft"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:layout_weight="1.0"
android:orientation="horizontal" &
android:id="@+id/tabs_tvMovieDetail"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:gravity="center"
android:text="故事梗概"
android:textColor="#eb8037"
android:textSize="16sp" /&
&/LinearLayout&
&LinearLayout
android:id="@+id/liLay_tabsMiddle"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:layout_weight="1.0"
android:orientation="horizontal" &
android:id="@+id/tabs_tvMovieComment"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:gravity="center"
android:text="剧本正文"
android:textSize="16sp" /&
&/LinearLayout&
&LinearLayout
android:id="@+id/liLay_tabsRight"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:layout_weight="1.0"
android:orientation="horizontal" &
android:id="@+id/tabs_tvMovieRavent"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:gravity="center"
android:text="人物介绍"
android:textSize="16sp" /&
&/LinearLayout&
&/LinearLayout&
&LinearLayout
android:id="@+id/re_tabLine"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="@+id/liLay_tabs"
android:background="#c8c7cc" &
&ImageView
android:id="@+id/tabLine"
android:layout_width="200dp"
android:layout_height="2.5dp"
android:background="#eb8037" /&
&/LinearLayout&
&com.junhuaceo.customscrollview.custom.CustomScrollView
android:id="@+id/customScrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/re_tabLine"
android:fadeScrollbars="true"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:scrollbarStyle="insideOverlay"
android:scrollbars="none" &
&RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" &
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#C8C7CC" /&
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text1"
android:layout_marginTop="15dp"
android:text="@string/text1"
android:textSize="16sp" /&
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@+id/text1"
android:layout_marginTop="15dp"
android:background="#C8C7CC" /&
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/line2"
android:layout_marginTop="15dp"
android:text="@string/text2"
android:textSize="16sp" /&
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@+id/text2"
android:layout_marginTop="15dp"
android:background="#C8C7CC" /&
android:id="@+id/text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/line3"
android:layout_marginTop="15dp"
android:text="@string/text3"
android:textSize="16sp" /&
&com.junhuaceo.customscrollview.custom.CustomListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/text3"
android:layout_marginTop="25dp"
android:divider="#C8C7CC"
android:dividerHeight="0.3dp" &
&/com.junhuaceo.customscrollview.custom.CustomListView&
&/RelativeLayout&
&/com.junhuaceo.customscrollview.custom.CustomScrollView&
android:id="@+id/commentMessageView"
android:layout_alignParentBottom="true"
layout="@layout/send_commentmessage_insert"
android:visibility="gone" /&
&/RelativeLayout&
重写的ScrollView控件代码CustomScrollView.java:
* 项目:CustomScrollView
* 包名:com.junhuaceo.customscrollview.custom
* @author Yuanjunhua
* 下午1:08:08
public class CustomScrollView extends ScrollView {
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
public CustomScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
private OnScrollL
public interface OnScrollListener{
void onScrollListener(int scrollY);
public void setOnScrollListener(OnScrollListener listener){
this.listener =
private int lastScrollY;
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
int scrollY = getScrollY();
if(lastScrollY != scrollY){
lastScrollY = scrollY;
mHandler.sendMessageDelayed(mHandler.obtainMessage(), 10);
public boolean onTouchEvent(android.view.MotionEvent ev) {
if(null != listener ){
listener.onScrollListener(lastScrollY = getScrollY());
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
mHandler.sendMessageDelayed(mHandler.obtainMessage(), 10);
return super.onTouchEvent(ev);
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
if(null != listener){
listener.onScrollListener(t);
mHandler.sendMessageDelayed(mHandler.obtainMessage(), 10);
重写的Listview代码CustomListView.java:
* 项目:CustomScrollView
* 包名:com.junhuaceo.customscrollview.custom
* @author Yuanjunhua
* 下午3:12:28
public class CustomListView extends ListView {
public CustomListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
public CustomListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE && 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
最后是MainActivity.java:
* 项目:CustomScrollView
* 包名:com.junhuaceo.customscrollview
* @author Yuanjunhua
* 上午11:03:09
public class MainActivity extends Activity implements OnScrollListener, OnClickListener{
private TextView line1;
private TextView line2;
private TextView line3;
private CustomScrollV
/** 屏幕的宽度
private int screenWidth, tabW
/** scroll 距离父控件的距离
private int scrollToParentD
/** line 距离父控件的距离
private int lineToParentDistance1,lineToParentDistance2,lineToParentDistance3;
/** line 高度
private int lineH
private LinearLayout liLeft,liMid,liR
private TextView tvLeft,tvMid,tvR
private TextView text1,text2,text3;
private ImageView tabL
private ListView listV
private LinkedList&CheckCommentsBean& listB
private DramaInsidePageA
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
View edtPopView = (View) msg.
edtPopView.setBackgroundResource(R.drawable.bg_black_color);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLeft=(TextView) findViewById(R.id.tabs_tvMovieDetail);
tvMid=(TextView) findViewById(R.id.tabs_tvMovieComment);
tvRight=(TextView) findViewById(R.id.tabs_tvMovieRavent);
text1 = (TextView) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);
text3 = (TextView) findViewById(R.id.text3);
setTextApointWordsColor();
liLeft=(LinearLayout) findViewById(R.id.liLay_tabsLeft);
liMid=(LinearLayout) findViewById(R.id.liLay_tabsMiddle);
liRight=(LinearLayout) findViewById(R.id.liLay_tabsRight);
liLeft.setOnClickListener(this);
liMid.setOnClickListener(this);
liRight.setOnClickListener(this);
tabLine=(ImageView) findViewById(R.id.tabLine);
line1 = (TextView) findViewById(R.id.line1);
line2 = (TextView) findViewById(R.id.line2);
line3 = (TextView) findViewById(R.id.line3);
SendCommentMessageInsertListViewUtil.getInstance().preInitViews(this, mHandler);
listView = (ListView) findViewById(R.id.listview);
cs = (CustomScrollView) findViewById(R.id.customScrollview);
cs.setOnScrollListener(this);
getScreen();
String heandUrl = "http://www.jxvdy.com/file/upload//11-17-52-65-3.jpg";
String content = "故事梗概:聚美优品百米冲刺奔向纽交所,给一批化妆品电商敲响警钟。美妆电商平台PBA正在寻找新的突破点,他们的首款智能硬件成为爆款。";
String name = "樱桃小丸子";
int age = 99;
listBean = new LinkedList&CheckCommentsBean&();
for (int i = 0; i & 15; i++) {
listBean.add(new CheckCommentsBean(heandUrl, name, age, content));
adapter = new DramaInsidePageAdapter(this, listBean);
listView.setAdapter(adapter);
/** 窗口有焦点的时候,即所有的布局绘制完毕的时候,我们来获取购买布局的高度和myScrollView距离父类布局的顶部位置
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
lineHight = line1.getHeight();
lineToParentDistance1 = line1.getTop();
lineToParentDistance2 = line2.getTop();
lineToParentDistance3 = line3.getTop();
scrollToParentDistance = cs.getTop();
滚动的回调方法,当滚动的Y距离大于或者等于 标题内容距离父类布局顶部的位置,就选中其对应的标题 */
public void onScrollListener(int scrollY) {
// TODO Auto-generated method stub
if(scrollY &= (lineToParentDistance1 + lineHight) & scrollY & (lineToParentDistance2 + lineHight)){
reSetTextColor();
LayoutParams lp = (LayoutParams) tabLine.getLayoutParams();
lp.leftMargin = 0;
tabLine.setLayoutParams(lp);
tvLeft.setTextColor(Color.parseColor("#eb8037"));
}else if(scrollY &= (lineToParentDistance2 + lineHight) & scrollY & (lineToParentDistance3 + lineHight)){
reSetTextColor();
LayoutParams lp = (LayoutParams) tabLine.getLayoutParams();
lp.leftMargin = screenWidth / 3;
tabLine.setLayoutParams(lp);
tvMid.setTextColor(Color.parseColor("#eb8037"));
}else if(scrollY &= (lineToParentDistance3 + lineHight)){
reSetTextColor();
LayoutParams lp = (LayoutParams) tabLine.getLayoutParams();
lp.leftMargin = 2 * screenWidth / 3;
tabLine.setLayoutParams(lp);
tvRight.setTextColor(Color.parseColor("#eb8037"));
/** 重新设置字体颜色 */
private void reSetTextColor(){
tvLeft.setTextColor(Color.parseColor("#000000"));
tvMid.setTextColor(Color.parseColor("#000000"));
tvRight.setTextColor(Color.parseColor("#000000"));
/** 获取屏幕的宽度 */
private void getScreen(){
DisplayMetrics outMetrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
screenWidth = outMetrics.widthP
tabWidth = (int) (1.0 * screenWidth / 3);
LayoutParams lp=(LayoutParams) tabLine.getLayoutParams();
lp.width=tabW
tabLine.setLayoutParams(lp);
* 设置文字中被选中字的颜色
private void setTextApointWordsColor(){
String txt1 = getResources().getString(R.string.text1);
SpannableStringBuilder style1 = new SpannableStringBuilder(txt1);
style.setSpan(new BackgroundColorSpan(Color.RED), 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); // 设置指定位置textview的背景颜色
style1.setSpan(new ForegroundColorSpan(Color.GRAY),0,5,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置指定位置文字的颜色
String txt2 = getResources().getString(R.string.text2);
SpannableStringBuilder style2 = new SpannableStringBuilder(txt2);
style.setSpan(new BackgroundColorSpan(Color.RED), 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); // 设置指定位置textview的背景颜色
style2.setSpan(new ForegroundColorSpan(Color.GRAY),0,5,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置指定位置文字的颜色
String txt3 = getResources().getString(R.string.text3);
SpannableStringBuilder style3 = new SpannableStringBuilder(txt3);
style.setSpan(new BackgroundColorSpan(Color.RED), 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); // 设置指定位置textview的背景颜色
style3.setSpan(new ForegroundColorSpan(Color.GRAY),0,5,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置指定位置文字的颜色
text1.setText(style1);
text2.setText(style2);
text3.setText(style3);
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.liLay_tabsLeft:
cs.scrollTo(0, lineToParentDistance1);
case R.id.liLay_tabsMiddle:
cs.scrollTo(0, lineToParentDistance2);
case R.id.liLay_tabsRight:
cs.scrollTo(0, lineToParentDistance3);
接下来让我们分析代码:
首先分析CustomScrollView.java:
重写onScrollChanged方法,是为了在ScrollView上下滑动的时候进行滑动位置的监听,并通过自定义的监听接口在外部调用。在滑动监听的过程中,每隔10ms发送handler一次,记录下当前距离父控件顶部的距离scrollY;
重写onTouchEvent方法,是为了在通过触摸使ScrollView上下滑动时候,在自定义的接口外部调用过程中每当手指离开屏幕后10ms后发送handler一次,并记录下当前距离父控件顶部的距离scrollY;
然后分析CustomListView.java:
重写onMeasure方法,是为了解决冲突&当ListView嵌套在ScrollView中的时候,ListView无法显示所有item或者只能显示一条item&;冲写onMeasure方法改变heightMeasureSpec大小属性使ListView中的所有item都能完全显示出来;
最后分享MainActivity.java:
这里改变指定字体颜色,即改变任意textView中的某些文字的颜色;程序使用这几句代码:
String txt1 = getResources().getString(R.string.text1);
SpannableStringBuilder style1 = new SpannableStringBuilder(txt1);
style.setSpan(new BackgroundColorSpan(Color.RED), 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); // 设置指定位置textview的背景颜色
style1.setSpan(new ForegroundColorSpan(Color.GRAY),0,5,Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置指定位置文字的颜色
text1.setText(style1);
MainActivity中控制ScrollView滑动过程根据滑动距离来选中标题文字思路是这样的:首先在重写的ScrollView中通过onTouchEvent方法和onScrollChanged方法,是的在屏幕中页面滑动的过程中能记录下当前ScrollView页面滑动的距离位置,也就是说:把ScrollView看做一张A4的纸的话,在一个A4纸大小的页面,记录下这张A4纸的顶部距离其所在页面顶部的距离大小的绝对值。然后在MainActivity中回调的过程拿ScrollY与那三个标题对应的文章TextView&本身是控件&所获得的距离页面顶部距离大小的绝对值进行比较,并选中页面内容对应的标题。

我要回帖

更多关于 父布局拦截点击事件 的文章

 

随机推荐