一、問題描述 |
本系列將結合案例應用,陸續向大家介紹一些Android典型界面的設計,首先說說tab導航,導航分為一層和兩層(底部區塊+區域內頭部導航),主要實現方案有RadioGroup+ViewPage+Fragment、Viewpager Indicator、ActionBar Tabs、FragmentTabHost+Fragment等,下面我們先采用RadioGroup+ViewPage+Fragment實現區域頭部導航。
如圖所示:
二、案例主要組件 |
1、先看一下MainActivity布局
<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/hvChannel" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="none" > <RadioGroup android:id="@+id/rgChannel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> </RadioGroup> </HorizontalScrollView> <android.support.v4.view.ViewPager android:id="@+id/vpNewsList" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </android.support.v4.view.ViewPager> </LinearLayout>
2、MainActivity代碼:
public class MainActivity extends FragmentActivity implements OnPageChangeListener{ private ViewPager viewPager; private RadioGroup rgChannel=null; private HorizontalScrollView hvChannel; private PageFragmentAdapter adapter=null; private List<Fragment> fragmentList=new ArrayList<Fragment>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ rgChannel=(RadioGroup)super.findViewById(R.id.rgChannel); viewPager=(ViewPager)super.findViewById(R.id.vpNewsList); hvChannel=(HorizontalScrollView)super.findViewById(R.id.hvChannel); rgChannel.setOnCheckedChangeListener( new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { viewPager.setCurrentItem(checkedId); } }); viewPager.setOnPageChangeListener(this); initTab();//動態產生RadioButton initViewPager(); rgChannel.check(0); } private void initTab(){ List<Channel> channelList=ChannelDb.getSelectedChannel(); for(int i=0;i<channelList.size();i++){ RadioButton rb=(RadioButton)LayoutInflater.from(this). inflate(R.layout.tab_rb, null); rb.setId(i); rb.setText(channelList.get(i).getName()); RadioGroup.LayoutParams params=new RadioGroup.LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT); rgChannel.addView(rb,params); } } private void initViewPager(){ List<Channel> channelList=ChannelDb.getSelectedChannel(); for(int i=0;i<channelList.size();i++){ NewsFragment frag=new NewsFragment(); Bundle bundle=new Bundle(); bundle.putString("weburl", channelList.get(i).getWeburl()); bundle.putString("name", channelList.get(i).getName()); frag.setArguments(bundle); //向Fragment傳入數據 fragmentList.add(frag); } adapter=new PageFragmentAdapter(super.getSupportFragmentManager(),fragmentList); viewPager.setAdapter(adapter); //viewPager.setOffscreenPageLimit(0); } /** * 滑動ViewPager時調整ScroollView的位置以便顯示按鈕 * @param idx */ private void setTab(int idx){ RadioButton rb=(RadioButton)rgChannel.getChildAt(idx); rb.setChecked(true); int left=rb.getLeft(); int width=rb.getMeasuredWidth(); DisplayMetrics metrics=new DisplayMetrics(); super.getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth=metrics.widthPixels; int len=left+width/2-screenWidth/2; hvChannel.smoothScrollTo(len, 0);//滑動ScroollView } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position) { // TODO Auto-generated method stub setTab(position); } }
其中initTab()方法實現向RadioGroup動態添加RadioButton
導航按鈕數據來源於ChannelDb
private static List<Channel> selectedChannel=new ArrayList<Channel>(); static{ selectedChannel.add(new Channel("","頭條",0,"","")); selectedChannel.add(new Channel("","娛樂",0,"","")); selectedChannel.add(new Channel("","體育",0,"","")); selectedChannel.add(new Channel("","財經",0,"","")); selectedChannel.add(new Channel("","熱點",0,"","")); selectedChannel.add(new Channel("","科技",0,"","")); selectedChannel.add(new Channel("","圖片",0,"","")); selectedChannel.add(new Channel("","汽車",0,"","")); selectedChannel.add(new Channel("","時尚",0,"","")); } public static List<Channel> getSelectedChannel(){ return selectedChannel; }
導航按鈕外觀:tab_rb.xml和tab_selector.xml背景選擇器(實現選擇后帶紅色下划線效果)
<?xml version="1.0" encoding="utf-8"?> <RadioButton xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="30dp" android:text="今日" android:background="@drawable/tab_selector" android:paddingLeft="15dp" android:paddingRight="15dp" android:paddingTop="10dp" android:paddingBottom="10dp" android:button="@null" /> tab_selector.xml: <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_checked="true" ><!-- 選中狀態 --> <layer-list > <item > <shape android:shape="rectangle"> <stroke android:width="5dp" android:color="#ff0000"/> </shape> </item> <item android:bottom="5dp" > <shape android:shape="rectangle" > <solid android:color="#fff"/> </shape> </item> </layer-list> </item> <item ><!-- 默認狀態 --> <shape > <solid android:color="#FAFAFA"/> </shape> </item> </selector>
3、PageFragmentAdapter適配器
public class PageFragmentAdapter extends FragmentPagerAdapter{ private List<Fragment> fragmentList; private FragmentManager fm; public PageFragmentAdapter(FragmentManager fm,List<Fragment> fragmentList){ super(fm); this.fragmentList=fragmentList; this.fm=fm; } @Override public Fragment getItem(int idx) { return fragmentList.get(idx%fragmentList.size()); } @Override public int getCount() { return fragmentList.size(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; //沒有找到child要求重新加載 } }
4、NewsFragment組件:
public class NewsFragment extends Fragment { private String weburl; private String channelName; @Override public void onAttach(Activity activity) { super.onAttach(activity); } private View view; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(view==null){//優化View減少View的創建次數 //該部分可通過xml文件設計Fragment界面,再通過LayoutInflater轉換為View組件 //這里通過代碼為fragment添加一個TextView TextView tvTitle=new TextView(getActivity()); tvTitle.setText(channelName); tvTitle.setTextSize(16); tvTitle.setGravity(Gravity.CENTER); tvTitle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); view=tvTitle; } ViewGroup parent=(ViewGroup)view.getParent(); if(parent!=null){//如果View已經添加到容器中,要進行刪除,負責會報錯 parent.removeView(view); } return view; } @Override public void setArguments(Bundle bundle) {//接收傳入的數據 weburl=bundle.getString("weburl"); channelName=bundle.getString("name"); } }
想要了解更多內容的小伙伴,可以點擊查看源碼,親自運行測試。
疑問咨詢或技術交流,請加入官方QQ群: (452379712)
作者:
傑瑞教育
出處: http://www.cnblogs.com/jerehedu/
本文版權歸煙台傑瑞教育科技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
出處: http://www.cnblogs.com/jerehedu/
本文版權歸煙台傑瑞教育科技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。