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



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

如图:

package zhangphil.tabs;

import java.util.ArrayList;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBarActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.graphics.Color;
import android.os.Bundle;

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

*
 * 思路:实现方案非常多。本例是把一个水平的LinearLayout在外层用HorizontalScrollView包裹起来(之所以使用HorizontalScrollView再包裹一层,是考虑到选项卡条目可能非常多的情况下,让用户能够像ListView一样滑动选择。否则,单纯的使用LinearLayout加入有限条目超过边界后多的元素不可见)。然后在LinearLayout里面加入若干子元素(简单期间,就比方TextView),做成一个横向可滑动且响应触发点击事件的"ListView"。该“ListView”响应点击事件,触发ViewPager页面的切换。

* 实现目的:tab栏中的选项和ViewPager中的Fragment实时联动。比方。当ViewPager滑动到第10的位置时候,对应的位于顶部(或者底部)的tab也要切换到第十的位置。反之亦然。
 * 这样的控件效果使用极为广泛。尤其是在一些新闻client中常见,比方新浪新闻、腾讯新闻新闻client的头部标签导航选项卡。
 *
 *
 * 附參考文章: 怎样让一个View的焦点改变时同一时候改变其附属元素。可參考我的还有一篇文章:
 * 《Android实现连续并排的若干个TextView单击改变背景颜色达到选项卡Tab栏切换效果 》
 * 链接地址:http://blog.csdn.net/zhangphil/article/details/46547561
 *
 *
 * */

public class MainActivity extends ActionBarActivity {

	private ArrayList<Fragment> fragments;

	// 測试的Fragment数量,也即是选项卡片的数量。

private final int SIZE = 15;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		fragments = new ArrayList<Fragment>();
		for (int i = 0; i < SIZE; i++) {
			Fragment f = TestFragment.newInstance(i);
			fragments.add(f);
		}

		// 将在tabs_LinearLayout里面加入须要的若干选项卡片。
		final LinearLayout tabs_LinearLayout = (LinearLayout) findViewById(R.id.tabs_LinearLayout);

		final ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);

		for (int i = 0; i < SIZE; i++) {
			View v = LayoutInflater.from(this).inflate(R.layout.view, null);
			TextView tv = (TextView) v;
			tv.setText("tab" + i);

			v.setOnFocusChangeListener(new OnFocusChangeListener() {

				@Override
				public void onFocusChange(View v, boolean hasFocus) {

					// 当用户选择了tab选项卡上面的子元素时候,对应的把ViewPager显示的页面调整到对应位置。

					int count = tabs_LinearLayout.getChildCount();
					for (int i = 0; i < count; i++) {
						View cv = tabs_LinearLayout.getChildAt(i);
						if (v == cv) {
							if (hasFocus) {
								mViewPager.setCurrentItem(i);
								break;
							}
						}
					}
				}
			});

			tabs_LinearLayout.addView(v, i);
		}

		mViewPager.setAdapter(new MyFragmentPagerAdapter(this
				.getSupportFragmentManager()));
		mViewPager.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageSelected(int pos) {
				// 在这里,当用户翻动ViewPager页面时候,对应的把选项卡显示对应的位置。
				// 最轻巧的实现就是让tab选项卡栏中的子元素获得焦点就可以。
				View v = tabs_LinearLayout.getChildAt(pos);
				v.requestFocus();
			}
		});
	}

	// ViewPager的适配器。
	private class MyFragmentPagerAdapter extends FragmentPagerAdapter {

		public MyFragmentPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int pos) {
			return fragments.get(pos);
		}

		@Override
		public int getCount() {
			return fragments.size();
		}
	}

	// 只用于測试的Fragment。

public static class TestFragment extends Fragment {

		// 用一个id标明。否则难以识别效果。
		private static final String ID = "id";

		public static Fragment newInstance(int id) {
			Fragment f = new TestFragment();
			Bundle b = new Bundle();
			b.putInt(ID, id);
			f.setArguments(b);
			return f;
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {

			Bundle bundle = this.getArguments();
			int id = (Integer) bundle.get(ID);

			TextView tv = new TextView(this.getActivity());
			tv.setGravity(Gravity.CENTER);
			tv.setText("Fragment:" + id);
			tv.setTextSize(50.0f);
			tv.setTextColor(Color.LTGRAY);

			return tv;
		}
	}
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?

>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <HorizontalScrollView
        android:id="@+id/tabs_HorizontalScrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" >

        <LinearLayout
            android:id="@+id/tabs_LinearLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:layout_weight="1" >

        </LinearLayout>

    </HorizontalScrollView>

    <View
        android:layout_width="match_parent"
        android:layout_height="5dip"
        android:background="@android:color/black" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="9" />

</LinearLayout>

view.xml:

<?xml version="1.0" encoding="utf-8"?

>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/selector"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:gravity="center"
    android:padding="5dip" >

</TextView>

selector.xml:

<?xml version="1.0" encoding="utf-8"?

>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/red" android:state_focused="true"/>
    <item android:drawable="@drawable/orange" android:state_pressed="true"/>
    <item android:drawable="@drawable/green"/>

</selector>

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

时间: 2024-08-13 10:20:19

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

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

欢迎转载,转载请注明出处http://blog.csdn.net/l664675249/article/details/50738102 介绍 点击事件的事件分发就是对MotionEvent事件的分发过程,当一个MotionEvent产生了以后,系统需要把这个事件传递给一个具体的View,而这个传递的过程就是分发的过程. 涉及到的三个方法 dispatchTouchEvent:用来进行事件的分发,如果事件能够传递给当前View,那么此方法一定会被调用,返回结果受当前View的onTouchEve

Android中View的事件分发机制

简介 事件也称MotionEvent,事件分发机制就是对MotionEvent事件的分发过程,即当一个MotionEvent发生之后,系统需要把这个事件传递给一个具体的View. 点击事件的分发过程由三个函数共同完成: dispatchTouchEvent(DTE) - 进行事件的分发,如果时间能够传递给当前View,该方法会被调用,返回结果受当前view的onTouchEvent, 子View的dispatchTouchEvent影响,表示是否消耗当前事件. onInterceptTouchE

Android中view的事件

view:top.left.right.bottom,相对于parent的位置参数,获取通过get*()来获取.width=right-left.height=bottom-top.x=left+translationx,y=top+translationY.translationX和translationY默认都是0,在view平移过程中top和left是不变的,x.y和translationX.translationY变化. motionEvent,TouchSlop VelocityTra

第23章、OnFocuChangeListener焦点事件(从零开始学Android)

在Android App应用中,OnFocuChangeListener焦点事件是必不可少的,我们在上一章的基础上来学习一下如何实现. 基本知识点:OnFocuChangeListener事件 一.界面 打开“res/layout/activity_main.xml”文件. 1.分别从工具栏向activity拖出2个编辑框EditText.控件来自Form Widgets. 2.打开activity_main.xml文件. [html] view plaincopy <LinearLayout

Android View触摸屏事件派发机制详解与源码分析

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 1.背景 最近在简书和微博还有Q群看见很多人说Android自定义控件(View/ViewGroup)如何学习?为啥那么难?其实答案很简单:"基础不牢,地动山摇." 不扯蛋了,进入正题.就算你不自定义控件,你也必须要了解Android控件的触摸屏事件传递机制(之所以说触摸屏是因为该

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

Android艺术开发探索第三章----View的事件体系(下) 在这里就能学习到很多,主要还是对View的事件分发做一个体系的了解 一.View的事件分发 上篇大致的说了一下View的基础知识和滑动,现在我们再来聊聊一个比较核心的知识点,那就是事件分发了,而且他还是一个难点,我们更加应该掌握,View的滑动冲突一直都是很苦恼的,这里,我们就来一起探索一下 1.点击事件的传递规则 我们分析的点击事件可不是View.OnClickListener,而是我们MotionEvent,即点击事件,关于M

Android View的事件分发机制

准备了一阵子,一直想写一篇事件分发的文章总结一下.这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等.这些子View的外层还有ViewGroup.如RelativeLayout.LinearLayout.作为一个开发人员,我们会思考.当点击一个button,Android系统是如何确定我点的就是button而不是TextView的?然后还正确的响应了button的点击事件. 内部经过了一系列什么过程呢? 先铺垫一些知识能更加清晰的理解事件分

android知识回顾--view的事件体系

1.view的滑动,六种滑动方式:    一:通过layout来实现滑动效果      package com.example.testdragview; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class DragView

Android事件分发详解(一)——View的事件分发

MainActivity如下: package cc.cv; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widge