通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果
来源:互联网 发布:c 语言入门自学 编辑:程序博客网 时间:2024/06/09 07:36
点击这里源码下载
看到了吗?就是这种效果:我再跟大家简单的叙述一下;
头部标题有三个:剧本梗概、剧本正文、剧本介绍。
当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" > <TextView 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" > <TextView 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" > <TextView 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" > <TextView android:id="@+id/line1" android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#C8C7CC" /> <TextView 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" /> <TextView 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" /> <TextView 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" /> <TextView 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" /> <TextView 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> <include 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 * * 2014-9-25下午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 OnScrollListener listener;public interface OnScrollListener{void onScrollListener(int scrollY);}public void setOnScrollListener(OnScrollListener listener){this.listener = 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);}};};@Overridepublic 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);break;}return super.onTouchEvent(ev);}; @Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {// TODO Auto-generated method stubsuper.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 * * 2014-9-25下午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}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
/** * * 项目:CustomScrollView * 包名:com.junhuaceo.customscrollview * @author Yuanjunhua * * 2014-9-25上午11:03:09 */public class MainActivity extends Activity implements OnScrollListener, OnClickListener{private TextView line1;private TextView line2;private TextView line3;private CustomScrollView cs;/** 屏幕的宽度 */private int screenWidth, tabWidth;/** scroll 距离父控件的距离 */private int scrollToParentDistance;/** line 距离父控件的距离 */private int lineToParentDistance1,lineToParentDistance2,lineToParentDistance3;/** line 高度 */ private int lineHight; private LinearLayout liLeft,liMid,liRight; private TextView tvLeft,tvMid,tvRight; private TextView text1,text2,text3; private ImageView tabLine; private ListView listView; private LinkedList<CheckCommentsBean> listBean; private DramaInsidePageAdapter adapter;private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {View edtPopView = (View) msg.obj;edtPopView.setBackgroundResource(R.drawable.bg_black_color);};};@Overrideprotected 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/201409/02/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距离父类布局的顶部位置 */@Overridepublic void onWindowFocusChanged(boolean hasFocus) {// TODO Auto-generated method stubsuper.onWindowFocusChanged(hasFocus);if(hasFocus){lineHight = line1.getHeight();lineToParentDistance1 = line1.getTop();lineToParentDistance2 = line2.getTop();lineToParentDistance3 = line3.getTop();scrollToParentDistance = cs.getTop();}}/** 滚动的回调方法,当滚动的Y距离大于或者等于 标题内容距离父类布局顶部的位置,就选中其对应的标题 */@Overridepublic void onScrollListener(int scrollY) {// TODO Auto-generated method stubif(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.widthPixels;tabWidth = (int) (1.0 * screenWidth / 3);LayoutParams lp=(LayoutParams) tabLine.getLayoutParams();lp.width=tabWidth;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);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.liLay_tabsLeft:cs.scrollTo(0, lineToParentDistance1);break;case R.id.liLay_tabsMiddle:cs.scrollTo(0, lineToParentDistance2);break;case R.id.liLay_tabsRight:cs.scrollTo(0, lineToParentDistance3);break;default:break;}}}
接下来让我们分析代码:
首先分析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<本身是控件>所获得的距离页面顶部距离大小的绝对值进行比较,并选中页面内容对应的标题。
建一个群,方便大家交流:蹦蹦哒Android <群号:423923313>
- 通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果
- 上下滑动的Listview
- ListView,ScrollView,RecyclerView上下滑动监听
- scrollview 上下滑动 禁止弹回效果
- 监听ScrollView 的上下滑动
- android listview/ScrollView 去除顶部下拉时的半月形阴影和上下滑动顶部和底部的虚化
- android listview/ScrollView 去除顶部下拉时的半月形阴影和上下滑动顶部和底部的虚化
- android listview或者ScrollView 去除顶部下拉时的蓝底或者上下滑动顶部和底部的虚化
- 通过反射去除listView 滑动到上下顶端的阴影
- ScrollView和ListView的滑动冲突解决
- ScrollView、ListView、GridView去掉边缘的蓝边和滑动条,改变item点击效果
- Android 重写ScrollView控件,以至于上下拖动时获取正确的滚动位置
- ScrollView嵌套listview滑动位置底部bug
- scrollView和listView的滑动冲突和listView显示不全
- scrollview 和 listview滑动冲突
- ScrollView和ListView滑动冲突
- Android中Scrollview、ViewPager、ListView,使ScrollView滑动到开始的位置。
- listView当选中上下滑动的时候背景是白色的
- Android_InstanceState
- android 打包自己的自定义组件成JAR包
- 利用DAC(Data-tier Application)实现数据库结构迁移
- 安卓横竖屏切换
- POI 设置单元格背景颜色
- 通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果
- cron表达式验证
- 命令行 error D8021: 无效的数值参数“/Wno-deprecated”
- 数组型参数使用
- 20140925百度校园招聘二面
- UVA - 11178 Morley's Theorem //几何初探
- iOS CGContextRef画图小结
- 关于做ceb转换cebx遇到的问题及解决方案总结
- 利用DAC(Data-tier Application)实现数据库结构迁移