目前很多应用都是支持滑动切换的,其中实现原理是,顶部是一个RadioGroup + 下面的线条 (我用的是填充)Imageview。
写这个Demo的整个思维是这样的,相当于是图层,最底层是一个Fragment,接着分为顶部 FirstRadioGroup 和 下半部分 ViewPager;然后我这里ViewPager里也是一层Fragment,即下面代码里命名的ContentFragment。
导航栏的菜单是可以在代码里随意添加的,不是固定布局,所以贴出布局代码 :fragment_home.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="match_parent"
android:background="@android:color/white">
<android.com.test.FirstRadioGroup
android:id="@+id/first_radio_group"
android:layout_width="match_parent"
android:layout_height="40dip">
<RelativeLayout
android:id="@+id/radio_group_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
>
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@android:color/white">
</RadioGroup>
<ImageView
android:id="@+id/indicator"
android:layout_width="1dip"
android:layout_height="2dip"
android:background="#577fbc"
android:layout_alignParentBottom="true"
android:scaleType="matrix"
/>
</RelativeLayout>
</android.com.test.FirstRadioGroup>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/first_radio_group">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</RelativeLayout>
我这边的导航标签不支持滑动,如果需要滑动,可以在FirstRadioGroup外面嵌套一层横向滑动的HorizontalScrollView,就可以了,下面贴FirstRadioGroup类的代码
package android.com.test;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class FirstRadioGroup extends FrameLayout {
private View view;
private Activity mContext;
private LayoutInflater mInflater;
private RadioGroup mRadioGroup;
private ImageView mIndicatorImg;
private int count;//标签个数
private int indicatorWidth;//每个标签的宽度
private int currentIndicatorLeft = 0;
private ViewPager mViewPager;
public void setSomeParam(View view, ViewPager mViewPager, int[] ids,Activity context) {
this.mContext = context;
this.view = view;
this.mViewPager = mViewPager;
mInflater = LayoutInflater.from(context);
DisplayMetrics dm = new DisplayMetrics();
this.mContext.getWindowManager().getDefaultDisplay().getMetrics(dm);
int windowWitdh = dm.widthPixels;
this.count = ids.length;
indicatorWidth = windowWitdh / count;
init(ids);
}
public FirstRadioGroup(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public FirstRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
private void init(int[] ids) {
mRadioGroup = (RadioGroup) view.findViewById(R.id.radio_group);
mIndicatorImg = (ImageView) view.findViewById(R.id.indicator);
initIndicatorWidth();
initNavigationHSV(ids);
setListener();
}
//初始化滑动下标的宽
private void initIndicatorWidth() {
ViewGroup.LayoutParams cursor_Params = mIndicatorImg
.getLayoutParams();
cursor_Params.width = indicatorWidth;
mIndicatorImg.setLayoutParams(cursor_Params);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void initNavigationHSV(int[] ids) {
mRadioGroup.removeAllViews();
for (int i = 0; i < this.count; i++) {
RadioButton rb = (RadioButton) mInflater.inflate(
R.layout.first_radiogroup_item, null);
rb.setId(i);
rb.setText(ids[i]);
rb.setBackground(null);
rb.setLayoutParams(new LayoutParams(indicatorWidth,
LayoutParams.MATCH_PARENT));
mRadioGroup.addView(rb);
}
mRadioGroup.check(0);
}
private void setListener() {
mRadioGroup
.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (mRadioGroup.getChildAt(checkedId) != null) {
moveAnimation(checkedId);
mViewPager.setCurrentItem(checkedId); // ViewPager
}
}
});
}
//动画移动效果
private void moveAnimation(int checkedId){
TranslateAnimation animation = new TranslateAnimation(currentIndicatorLeft,
indicatorWidth * checkedId,0f, 0f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(200);
animation.setFillAfter(true);
// 执行位移动画
mIndicatorImg.startAnimation(animation);
// 记录当前 下标的距最左侧的 距离
currentIndicatorLeft = indicatorWidth * checkedId;
}}
HomeFragment.java
package android.com.test;
import android.app.Activity;
import android.os.Bundle;
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.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
/**
* Created by BaJie on 2015/11/18.
*/
public class HomeFragment extends BaseFragment {
static HomeFragment fragment = null;
private FragmentControlCenter mControlCenter;
private Fragment mFragment;
private Activity mThis;
RadioGroup mRadioGroup;
ViewPager mViewPager;
ImageView mIndicator;
FirstRadioGroup firstRadioGroup;
RelativeLayout mRedioGroupLayout;
public static HomeFragment newInstance() {
if (fragment == null) {
fragment = new HomeFragment();
}
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
}
@SuppressWarnings("ResourceType")
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mThis = getActivity();
mRadioGroup = (RadioGroup)view.findViewById(R.id.radio_group);
mViewPager = (ViewPager)view.findViewById(R.id.view_pager);
mIndicator = (ImageView)view.findViewById(R.id.indicator);
mRedioGroupLayout = (RelativeLayout)view.findViewById(R.id.radio_group_layout);
firstRadioGroup = (FirstRadioGroup) view.findViewById(R.id.first_radio_group);
mControlCenter = FragmentControlCenter.getInstance(mThis);
initViewPager();
int[] ids = {R.string.title_pic,R.string.title_haha};
firstRadioGroup.setSomeParam(mRedioGroupLayout, mViewPager, ids, mThis);
}
private void initViewPager() {
Log.i("smile", "initViewPager************* ");
mViewPager.setAdapter(new HomePagerAdapter(getChildFragmentManager()));
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mRadioGroup.check(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
private class HomePagerAdapter extends FragmentPagerAdapter {
public HomePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
mFragment = mControlCenter.getFragment(1);
setBundleArguments(mFragment, "BALABALA MO FA " + position);
return mFragment;
}
@Override
public int getCount() {
return 2;
}
}
private void setBundleArguments(Fragment fragment, String content) {
Bundle args = new Bundle();
args.putString("content", content);
Log.i("smile", "setBundleArguments ---------content = " + content);
fragment.setArguments(args);
}
}
ContentFragment.java
package android.com.test;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by BaJie on 2015/11/18.
*/
public class ContentFragment extends Fragment {
private TextView mTxt;
private Activity mThis;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_content, container,
false);
mTxt = (TextView) rootView.findViewById(R.id.content_txt);
mTxt.setText(getArguments().getString("content"));
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mThis = getActivity();
}
}
FragmentControlCenter.java
package android.com.test;
import android.content.Context;
import android.support.v4.app.Fragment;
public class FragmentControlCenter {
private static FragmentControlCenter instance;
private FragmentControlCenter(Context context) {
}
public static synchronized FragmentControlCenter getInstance(Context context) {
if (instance == null) {
instance = new FragmentControlCenter(context);
}
return instance;
}
public Fragment getFragment(int i) {
Fragment fragment = null;
switch (i) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new ContentFragment();
break;
}
return fragment;
}
}
fragment_content.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="match_parent"
android:background="@android:color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/content_txt"
android:textColor="@android:color/holo_red_dark"/>
</RelativeLayout>
first_radiogroup_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@android:color/holo_blue_bright"
android:button="@null"
android:checked="true"
android:gravity="center"
android:text=""
android:textSize="14.0sp"
android:textColor="@android:color/black"/>
下面是运行的截图: