目前很多应用都是支持滑动切换的,其中实现原理是,顶部是一个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"/>
下面是运行的截图: