《Android捕获View焦点事件,LinearLayout结合HorizontalScrollView实现ViewPgaer和选项卡Tabs联动。》

如图:

  1. package zhangphil.tabs;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. import android.support.v4.app.Fragment;
  6. import android.support.v4.app.FragmentManager;
  7. import android.support.v4.app.FragmentPagerAdapter;
  8. import android.support.v4.view.ViewPager;
  9. import android.support.v4.view.ViewPager.OnPageChangeListener;
  10. import android.support.v7.app.ActionBarActivity;
  11. import android.view.Gravity;
  12. import android.view.LayoutInflater;
  13. import android.view.View;
  14. import android.view.View.OnFocusChangeListener;
  15. import android.view.ViewGroup;
  16. import android.widget.LinearLayout;
  17. import android.widget.TextView;
  18. import android.graphics.Color;
  19. import android.os.Bundle;
  20.  
  21. /**
  22. *
  23. * Android捕获View焦点事件,LinearLayout结合HorizontalScrollView实现ViewPgaer和选项卡Tabs联动。
  24.  
  25. *
  26. * 思路:实现方案非常多。本例是把一个水平的LinearLayout在外层用HorizontalScrollView包裹起来(之所以使用HorizontalScrollView再包裹一层,是考虑到选项卡条目可能非常多的情况下,让用户能够像ListView一样滑动选择。否则,单纯的使用LinearLayout加入有限条目超过边界后多的元素不可见)。然后在LinearLayout里面加入若干子元素(简单期间,就比方TextView),做成一个横向可滑动且响应触发点击事件的"ListView"。该“ListView”响应点击事件,触发ViewPager页面的切换。
  27.  
  28. * 实现目的:tab栏中的选项和ViewPager中的Fragment实时联动。比方。当ViewPager滑动到第10的位置时候,对应的位于顶部(或者底部)的tab也要切换到第十的位置。反之亦然。
  29. * 这样的控件效果使用极为广泛。尤其是在一些新闻client中常见,比方新浪新闻、腾讯新闻新闻client的头部标签导航选项卡。
  30. *
  31. *
  32. * 附參考文章: 怎样让一个View的焦点改变时同一时候改变其附属元素。可參考我的还有一篇文章:
  33. * 《Android实现连续并排的若干个TextView单击改变背景颜色达到选项卡Tab栏切换效果 》
  34. * 链接地址:http://blog.csdn.net/zhangphil/article/details/46547561
  35. *
  36. *
  37. * */
  38.  
  39. public class MainActivity extends ActionBarActivity {
  40.  
  41. private ArrayList<Fragment> fragments;
  42.  
  43. // 測试的Fragment数量,也即是选项卡片的数量。
  44.  
  45. private final int SIZE = 15;
  46.  
  47. @Override
  48. protected void onCreate(Bundle savedInstanceState) {
  49. super.onCreate(savedInstanceState);
  50. setContentView(R.layout.activity_main);
  51.  
  52. fragments = new ArrayList<Fragment>();
  53. for (int i = 0; i < SIZE; i++) {
  54. Fragment f = TestFragment.newInstance(i);
  55. fragments.add(f);
  56. }
  57.  
  58. // 将在tabs_LinearLayout里面加入须要的若干选项卡片。
  59. final LinearLayout tabs_LinearLayout = (LinearLayout) findViewById(R.id.tabs_LinearLayout);
  60.  
  61. final ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);
  62.  
  63. for (int i = 0; i < SIZE; i++) {
  64. View v = LayoutInflater.from(this).inflate(R.layout.view, null);
  65. TextView tv = (TextView) v;
  66. tv.setText("tab" + i);
  67.  
  68. v.setOnFocusChangeListener(new OnFocusChangeListener() {
  69.  
  70. @Override
  71. public void onFocusChange(View v, boolean hasFocus) {
  72.  
  73. // 当用户选择了tab选项卡上面的子元素时候,对应的把ViewPager显示的页面调整到对应位置。
  74.  
  75. int count = tabs_LinearLayout.getChildCount();
  76. for (int i = 0; i < count; i++) {
  77. View cv = tabs_LinearLayout.getChildAt(i);
  78. if (v == cv) {
  79. if (hasFocus) {
  80. mViewPager.setCurrentItem(i);
  81. break;
  82. }
  83. }
  84. }
  85. }
  86. });
  87.  
  88. tabs_LinearLayout.addView(v, i);
  89. }
  90.  
  91. mViewPager.setAdapter(new MyFragmentPagerAdapter(this
  92. .getSupportFragmentManager()));
  93. mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
  94.  
  95. @Override
  96. public void onPageScrollStateChanged(int arg0) {
  97.  
  98. }
  99.  
  100. @Override
  101. public void onPageScrolled(int arg0, float arg1, int arg2) {
  102.  
  103. }
  104.  
  105. @Override
  106. public void onPageSelected(int pos) {
  107. // 在这里,当用户翻动ViewPager页面时候,对应的把选项卡显示对应的位置。
  108. // 最轻巧的实现就是让tab选项卡栏中的子元素获得焦点就可以。
  109. View v = tabs_LinearLayout.getChildAt(pos);
  110. v.requestFocus();
  111. }
  112. });
  113. }
  114.  
  115. // ViewPager的适配器。
  116. private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
  117.  
  118. public MyFragmentPagerAdapter(FragmentManager fm) {
  119. super(fm);
  120. }
  121.  
  122. @Override
  123. public Fragment getItem(int pos) {
  124. return fragments.get(pos);
  125. }
  126.  
  127. @Override
  128. public int getCount() {
  129. return fragments.size();
  130. }
  131. }
  132.  
  133. // 只用于測试的Fragment。
  134.  
  135. public static class TestFragment extends Fragment {
  136.  
  137. // 用一个id标明。否则难以识别效果。
  138. private static final String ID = "id";
  139.  
  140. public static Fragment newInstance(int id) {
  141. Fragment f = new TestFragment();
  142. Bundle b = new Bundle();
  143. b.putInt(ID, id);
  144. f.setArguments(b);
  145. return f;
  146. }
  147.  
  148. @Override
  149. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  150. Bundle savedInstanceState) {
  151.  
  152. Bundle bundle = this.getArguments();
  153. int id = (Integer) bundle.get(ID);
  154.  
  155. TextView tv = new TextView(this.getActivity());
  156. tv.setGravity(Gravity.CENTER);
  157. tv.setText("Fragment:" + id);
  158. tv.setTextSize(50.0f);
  159. tv.setTextColor(Color.LTGRAY);
  160.  
  161. return tv;
  162. }
  163. }
  164. }

activity_main.xml:

  1. <?xml version="1.0" encoding="utf-8"?
  2.  
  3. >
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical" >
  8.  
  9. <HorizontalScrollView
  10. android:id="@+id/tabs_HorizontalScrollView"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:scrollbars="none" >
  14.  
  15. <LinearLayout
  16. android:id="@+id/tabs_LinearLayout"
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent"
  19. android:orientation="horizontal"
  20. android:layout_weight="1" >
  21.  
  22. </LinearLayout>
  23.  
  24. </HorizontalScrollView>
  25.  
  26. <View
  27. android:layout_width="match_parent"
  28. android:layout_height="5dip"
  29. android:background="@android:color/black" />
  30.  
  31. <android.support.v4.view.ViewPager
  32. android:id="@+id/viewpager"
  33. android:layout_width="match_parent"
  34. android:layout_height="match_parent"
  35. android:layout_weight="9" />
  36.  
  37. </LinearLayout>

view.xml:

  1. <?xml version="1.0" encoding="utf-8"?
  2.  
  3. >
  4. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:background="@drawable/selector"
  8. android:clickable="true"
  9. android:focusable="true"
  10. android:focusableInTouchMode="true"
  11. android:gravity="center"
  12. android:padding="5dip" >
  13.  
  14. </TextView>

selector.xml:

  1. <?xml version="1.0" encoding="utf-8"?
  2.  
  3. >
  4. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  5.  
  6. <item android:drawable="@drawable/red" android:state_focused="true"/>
  7. <item android:drawable="@drawable/orange" android:state_pressed="true"/>
  8. <item android:drawable="@drawable/green"/>
  9.  
  10. </selector>

剩余的是在drawable文件夹下的一些基础的图片资源。能够依据自己须要加入。

Android捕获View焦点事件,LinearLayout结合HorizontalScrollView实现ViewPgaer和选项卡Tabs联动的更多相关文章

  1. Android中View的事件分发机制——Android开发艺术探索笔记

    原文链接 http://sparkyuan.me/ 转载请注明出处 介绍 点击事件的事件分发就是对MotionEvent事件的分发过程.当一个MotionEvent产生了以后,系统须要把这个事件传递给 ...

  2. Android中View的事件分发机制

    简介 事件也称MotionEvent,事件分发机制就是对MotionEvent事件的分发过程,即当一个MotionEvent发生之后,系统需要把这个事件传递给一个具体的View. 点击事件的分发过程由 ...

  3. Delphi XE5 android 捕获几个事件

    以下代码能监控到以下几个事件: FinishedLaunching     BecameActive     WillBecomeInactive    EnteredBackground    Wi ...

  4. Android中view的事件

    view:top.left.right.bottom,相对于parent的位置参数,获取通过get*()来获取.width=right-left.height=bottom-top.x=left+tr ...

  5. Win32-API: 终于能正常的捕获焦点事件: WM_COMMAND、BN_SETFOCUS、EN_SETFOCUS

    学习和使用win32-api来写窗口程序算算也有二三年了. 以前有个需求,想捕获控件的焦点事件(SETFOCUS. KILLFOCUS),我一直认为应该捕获 WM_SETFOCUS 和 WM_KILL ...

  6. Android View的事件分发机制和滑动冲突解决方案

    这篇文章会先讲Android中View的事件分发机制,然后再介绍Android滑动冲突的形成原因并给出解决方案.因水平有限,讲的不会太过深入,只希望各位看了之后对事件分发机制的流程有个大概的概念,并且 ...

  7. Android中Touch事件分析--解决HorizontalScrollView滑动和按钮事件触发问题

    之前写过关于HorizontalScrollView滑动和按钮事件触发问题,但是不能所有的情况,最近几天一直在想这个问题,今天有一个比较好的解决思路,最终应用在项目里面效果也很好,首先说明一下功能: ...

  8. Android View 的事件体系

    android 系统虽然提供了很多基本的控件,如Button.TextView等,但是很多时候系统提供的view不能满足我们的需求,此时就需要我们根据自己的需求进行自定义控件.这些控件都是继承自Vie ...

  9. Android艺术开发探索第三章————View的事件体系(下)

    Android艺术开发探索第三章----View的事件体系(下) 在这里就能学习到很多,主要还是对View的事件分发做一个体系的了解 一.View的事件分发 上篇大致的说了一下View的基础知识和滑动 ...

随机推荐

  1. 【金阳光測试】大话Android自己主动化測试--Android自己主动化系列(1)--金阳光于2013年4月份

    Android自己主动化測试框架和工具在四年多的发展日趋成熟. 从五年前的第一代自己主动化架构演进到眼下第四代(本系列讲座第7篇后将具体剖析第三代和第四代自己主动化框架)从曾经最早谷歌推崇的monke ...

  2. ubuntu 非长期支持版升级系统版本号(ssh登录情况适用)

    (1)当前系统为非长期支持版.而且已被废弃,仅仅能逐版本号升级 以当前系统版本号为11.10为例 改动source.list更新源为通用old源,由于原来的源已经不可用 deb http://old- ...

  3. node06---npm、silly-datetime、路径问题

    我们刚才学习了,模块就是一些功能的封装,所以一些成熟的.经常使用的功能,都有人封装成为了模块.并且放到了社区中,供人免费下载. 这个伟大的社区,叫做npm. 也是一个工具名字 node package ...

  4. java9新特性-11-String存储结构变更

    1. 官方Feature JEP254: Compact Strings 2. 产生背景 Motivation The current implementation of the String cla ...

  5. Java类和对象4

    编写Java应用程序.首先,定义一个Print类,它有一个方法void output(intx),如果x的值是1,在控制台打印出大写的英文字母表:如果x的值是2,在控制台打印出小写的英文字母表.其次, ...

  6. spinlock参考资料

    spinlock:http://irl.cs.ucla.edu/~yingdi/web/paperreading/smp_locking.pdf

  7. 51Nod 1007 正整数分组(01背包)

    将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. Input 第1行:一个数N,N为正整数的数量. ...

  8. 维生素C主要生理功能

    维C是:维生素C又叫抗坏血酸,是一种水溶性维生素. 维生素C主要生理功能 1. 促进骨胶原的生物合成.利于组织创伤口的更快愈合: 维生素C在体内参与多种反应,如参与氧化还原过程,在生物氧化和还原作用以 ...

  9. 关于git及其github的使用

    一:序言(就是瞎扯) 人们都说不会使用git和github的程序员都不是好程序员,是的,当我第一次听到的时候有点失望.因为我也不会...但是这句话激起了我学习使用git的动力(其实也没怎么深入的学习) ...

  10. MyBatis学习总结(17)——Mybatis分页插件PageHelper

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件. 分页插件支持任何复杂的单表.多表分页,部分特殊情况请看重要提示. 想要使用分页插件?请看如何使用分页插件. 物理分页 该 ...