您的位置:首页 > 移动开发 > Android开发

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

2018-01-04 00:00 218 查看


《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也要切换到第十的位置。反之亦然。
* 这种控件效果使用极为广泛,尤其是在一些新闻客户端中常见,比如新浪新闻、腾讯新闻新闻客户端的头部标签导航选项卡。
*
*
* 附参考文章: 如何让一个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目录下的一些基础的图片资源,可以根据自己需要添加。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐