android不继承FragmentActivity实现ViewPager+Fragment(标签的优化)
2016-09-23 16:35
447 查看
现在很多的ViewPager+Fragment都要Activity继承于FragmentActivity然后Adapter也是要继承于FragmentPagerAdapter实现的。然后我想想能不能直接用Activity跟PagerAdapter来实现。。。。当然了,也是项目需要。。接下来就是我的实现思路,其实就是改了一下PagerAdapter的instantiateItem函数就行
效果如下:(看代码,不要看图。。)
以下就是详细的代码:
布局:
以下就是改良版的。。。
MainActivity:
TabAdapter:
因为每个菜单项都是一个GridView子项,所以可以继承GridView然后实现自己的TabGridView,也可以直接用GridView。这个视情况而定了。TabGridView如下:
Tab:
viewpager_main.xml:
tab子项的xml文件:tab_layout:
效果如下:(看代码,不要看图。。)
以下就是详细的代码:
import java.util.ArrayList; import com.example.androidtest.R; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; public class MainViewPager extends Activity{ private ViewPager pager; ArrayList<Fragment> mFragmentList = new ArrayList<Fragment>(); ArrayList<String> titleContainer = new ArrayList<String>(); private ImageView[] indicator_imgs = new ImageView[2]; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewpager_main); pager = (ViewPager) this.findViewById(R.id.viewpager); //viewpager开始添加Fragment mFragmentList.add(new HomeFagment()); mFragmentList.add(new SecondFragment()); //设置ViewPager界面切换之间不会重新加载 pager.setOffscreenPageLimit(mFragmentList.size()); pager.setAdapter(new PagerAdapter() { //viewpager中的组件数量 @Override public int getCount() { return mFragmentList.size(); } //每次滑动的时候生成的组件 重点在这!!! @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment = mFragmentList.get(position); if (!fragment.isAdded()) { //判断当前的Fragment是否存在 FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.add(fragment, fragment.getClass().getSimpleName()); ft.commitAllowingStateLoss(); fragmentManager.executePendingTransactions(); } if (fragment.getView().getParent() == null) { container.addView(fragment.getView()); //把Fragment加到ViewPager里面 } return fragment.getView(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getItemPosition(Object object) { return super.getItemPosition(object); } @Override public CharSequence getPageTitle(int position) { return titleContainer.get(position); }}); pager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { // 改变所有导航的背景图片为:未选中 for (int i = 0; i < indicator_imgs.length; i++) { indicator_imgs[i].setBackgroundResource(R.drawable.home_off); } // 改变当前背景图片为:选中 indicator_imgs[arg0].setBackgroundResource(R.drawable.home_on); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); initIndicator(); } /** * 初始化引导图标 * 动态创建多个小圆点,然后组装到线性布局里 */ private void initIndicator(){ indicator_imgs[0] = (ImageView) findViewById(R.id.home_ic); indicator_imgs[1] = (ImageView) findViewById(R.id.game_ic); for (int i = 0; i < 2; i++) { if (i == 0) { // 初始化第一个为选中状态 indicator_imgs[i].setBackgroundResource(R.drawable.home_on); } else { indicator_imgs[i].setBackgroundResource(R.drawable.home_off); } } } }HomeFragment的话也就是随意的添加一个布局而已
import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * 首页 * */ public class HomeFagment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.guide_item1, null); } }
布局:
<?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" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" > </android.support.v4.view.ViewPager> <LinearLayout android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical" > <ImageView android:id="@+id/home_ic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/home_on" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="首页" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical" > <ImageView android:id="@+id/game_ic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/game_off" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="游戏" /> </LinearLayout> </LinearLayout> </LinearLayout>然后标签页的话也就是在个ViewPager滑动的时候设置监听:
@Override public void onPageSelected(int arg0) { // 改变所有导航的背景图片为:未选中 for (int i = 0; i < indicator_imgs.length; i++) { indicator_imgs[i].setBackgroundResource(R.drawable.home_off); } // 改变当前背景图片为:选中 indicator_imgs[arg0].setBackgroundResource(R.drawable.home_on); }这样的图片设置的话看起来不是很完美。。如果不是用一张图片的话可能要操作一大堆的逻辑关系,然后今天看到有一个用适配器的方法来更新底部的标题栏,这样在页面滑动的时候只要调用notifyDataSetChanged函数就可以了,当然了,用适配器的话肯定要配置适配器文件,但是配置完之后就方便了许多了。并且在以后如果底部的菜单栏发生变化的,修改起来也很方便,不需要去动配置文件啥的,只要改改一些代码。
以下就是改良版的。。。
MainActivity:
import java.util.ArrayList; import com.example.androidtest.R; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.ViewGroup; public class MainViewPager extends Activity{ private ViewPager pager; ArrayList<Fragment> mFragmentList = new ArrayList<Fragment>(); ArrayList<String> titleContainer = new ArrayList<String>(); private ArrayList<Tab> list = new ArrayList<Tab>(); private TabView tabView; private TabAdapter mAdapter; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewpager_main); pager = (ViewPager) this.findViewById(R.id.viewpager); tabView = (TabView) findViewById(R.id.tab); //viewpager开始添加Fragment mFragmentList.add(new HomeFagment()); mFragmentList.add(new SecondFragment()); Tab tabHome = new Tab(); //增加菜单项 tabHome.setName("首页"); tabHome.setIcon(R.drawable.home_icon);//这个地方设置的话不是单纯的一张图片 是一个drawable的select配置图片,这样才能在选中跟未选显示不同的图片 list.add(tabHome); Tab tabGame = new Tab(); tabGame.setName("游戏"); tabGame.setIcon(R.drawable.game_icon); list.add(tabGame); mAdapter = new TabAdapter(MainViewPager.this, list); tabView.setNumColumns(list.size());//设置底部菜单栏的个数 tabView.setAdapter(mAdapter); //设置ViewPager界面切换之间不会重新加载的页面数 pager.setOffscreenPageLimit(mFragmentList.size()); pager.setAdapter(new PagerAdapter() { //viewpager中的组件数量 @Override public int getCount() { return mFragmentList.size(); } //每次滑动的时候生成的组件 @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment = mFragmentList.get(position); if (!fragment.isAdded()) { //判断当前的Fragment是否存在 FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.add(fragment, fragment.getClass().getSimpleName()); ft.commitAllowingStateLoss(); fragmentManager.executePendingTransactions(); } if (fragment.getView().getParent() == null) { container.addView(fragment.getView()); //把Fragment加到ViewPager里面 } return fragment.getView(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getItemPosition(Object object) { return super.getItemPosition(object); } @Override public CharSequence getPageTitle(int position) { return titleContainer.get(position); }}); pager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { mAdapter.setSelectedPosition(arg0);//需要改动的话只要调用这两个代买,一个是设置选中的位置,一个是适配器更新 mAdapter.notifyDataSetChanged(); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); } }
TabAdapter:
import java.util.ArrayList; import com.example.androidtest.R; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; public class TabAdapter extends BaseAdapter{ private Context context; private ArrayList<Tab> list; public TabAdapter(Context context, ArrayList<Tab> list) { this.context = context; this.list = list; } private int selectedPosition = 0;// 选中的位置 //设置选中位置 public void setSelectedPosition(int position) { selectedPosition = position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHold viewhold; if (convertView == null) { viewhold = new ViewHold(); convertView = LayoutInflater.from(context).inflate(R.layout.tab_layout, parent, false);//加载单个tab的layout TextView name = (TextView) convertView.findViewById(R.id.tv_name);//tab名称 ImageView img = (ImageView) convertView.findViewById(R.id.iv_icon);//tab图标 viewhold.name = name; viewhold.img = img; convertView.setTag(viewhold); } else { viewhold = (ViewHold) convertView.getTag(); } viewhold.img.setBackgroundResource(list.get(position).getIcon()); viewhold.name.setText(list.get(position).getName()); if (position == selectedPosition) { //这个地方进行选中的颜色处理 选中的选项 viewhold.name.setTextColor(Color.RED); viewhold.img.setSelected(true); //图片设置为选中状态 } else { viewhold.name.setTextColor(Color.BLACK); viewhold.img.setSelected(false); } return convertView; } class ViewHold { TextView name; ImageView img; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return list.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } }
因为每个菜单项都是一个GridView子项,所以可以继承GridView然后实现自己的TabGridView,也可以直接用GridView。这个视情况而定了。TabGridView如下:
import android.content.Context; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; import android.widget.GridView; public class TabView extends GridView{ public TabView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public TabView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public TabView(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public boolean dispatchKeyEvent(KeyEvent event) { if(event.getAction() == MotionEvent.ACTION_MOVE){ return true;//禁止Gridview进行滑动 } return super.dispatchKeyEvent(event); } }
Tab:
/** * 菜单栏子项 */ public class Tab { String name;//tab名称 int icon;//tab图标 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getIcon() { return icon; } public void setIcon(int icon) { this.icon = icon; } }还有Drawable,就拿一个home_icon来看看:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/game_off" android:state_selected="false"></item> <item android:drawable="@drawable/game_on" android:state_selected="true"></item> </selector>
viewpager_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" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" > </android.support.v4.view.ViewPager> <com.example.viewpager.TabView android:id="@+id/tab" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
tab子项的xml文件:tab_layout:
<?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" > <ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/home_off" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="123" /> </LinearLayout>
相关文章推荐
- Android简单有效Viewpager+Fragment实现滑动标签页
- ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页
- Android ViewPager和Fragment实现顶部导航界面滑动效果、标签下的tab位置
- Android使用ViewPager+Fragment实现标签分页
- Android ViewPager + Fragment 实现滑动标签效果
- Android 通过ViewPager实现点击和滑动切换Fragment标签页
- ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应。
- android FragmentTabhost+ViewPager实现可滑动的标签页
- android 学习之Fragment+ViewPager实现页面左右滑动标签页
- android使用viewPager和Fragment实现滑动切换activity!
- android_使用ViewPager和Fragment实现滑动导航
- Android开发之ViewPager结合Fragment实现滑动页面的效果(源代码分享)
- Android 利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效
- Android之ActionBar、Tabs、Fragment、ViewPager实现标签页切换并缓存页面
- Android 利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效果(牛逼)
- 使用ViewPager+Fragment来实现带滚动条的多屏滑动-IndicatorFragmentActivity
- 使用ViewPager+Fragment来实现带滚动条的多屏滑动-IndicatorFragmentActivity
- 使用ViewPager+Fragment来实现带滚动条的多屏滑动-IndicatorFragmentActivity
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信