Android之碎片Fragment
Fragment是个特别的存在,有点像报纸上的专栏,看起来只占据页面的一小块,但是这一小块有自己的生命周期,可以自行其是,仿佛独立王国,并且这一小块的特性无论在哪个页面,给一个位置就行,添加以后不影响宿主页面的其他区域,去除后也不影响宿主页面的其他区域。每个fragment都有自己的布局文件,依据其使用方式可分为静态注册和动态注册两种,静态注册是在布局文件中直接放置fragment节点,类似于一个普通控件,可被多个布局文件同时引用。静态注册一般用于某个通用的页面部件(如logo条,广告条等),每个活动页面均可直接引用该部件。
1.静态注册
下面是fragment布局文件的代码:
<?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="wrap_content" android:orientation="horizontal" android:background="#bbffbb"> <TextView android:id="@+id/tv_adv" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textColor="#000" android:textSize="20sp" android:gravity="center" android:text="广告"/> <ImageView android:id="@+id/iv_adv" android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="5" android:src="@drawable/adv" android:scaleType="fitCenter"/> </LinearLayout>
下面是与上述文件对应的fragment代码,除了继承自fragment外,其他地方很像活动页代码:
package com.example.animator.highleveltools; import android.content.Context; import android.net.Uri; 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.ImageView; import android.widget.TextView; import android.widget.Toast; import java.util.zip.Inflater; public class BlankFragment extends Fragment implements View.OnClickListener{ private View mView; private Context mContext; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContext = getActivity();//获取活动页上下文 //根据布局文件fragment_static.xml生成视图对象 mView = inflater.inflate(R.layout.fragment_layout,container,false); TextView tv_adv = (TextView) mView.findViewById(R.id.tv_adv); ImageView iv_adv = (ImageView) mView.findViewById(R.id.iv_adv); tv_adv.setOnClickListener(this); iv_adv.setOnClickListener(this); return mView;//返回该碎片的视图对象 } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } @Override public void onClick(View view) { if(view.getId()==R.id.tv_adv){ Toast.makeText(mContext,"您点击了广告文本",Toast.LENGTH_LONG).show(); }else if(view.getId()==R.id.iv_adv){ Toast.makeText(mContext,"您点击了广告图片",Toast.LENGTH_LONG).show(); } } }
若想在页面布局文件中引用fragment,则可直接加入一个fragment节点,注意节点要增加name属性指定fragment类的完整路径
<LinearLayout 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:orientation="vertical" android:padding="5dp" > <fragment android:id="@+id/fragment_static" android:layout_width="match_parent" android:layout_height="wrap_content" android:name="com.example.animator.highleveltools.BlankFragment" tools:layout="@layout/fragment_layout" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center|top" android:text="这是每个页面的具体内容" android:textColor="#000" android:textSize="17sp"/> </LinearLayout>
运行效果如下:
2.动态注册
相比静态注册,动态注册用的更多,动态注册知道在代码中才动态添加fragment,动态生成的碎片就是给翻页视图用的。使用碎片适配器即可实现:
package adapter; import android.app.FragmentManager; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentStatePagerAdapter; import android.text.style.DynamicDrawableSpan; import java.util.ArrayList; import bean.DynamicFragment; /** * Created by animator on 2020/1/29. */ public class MobilePagerAdapter extends FragmentStatePagerAdapter { private ArrayList<GoodsInfo> mGoodsList = new ArrayList<>();//声明一个商品队列 //碎片页适配器的构造函数,传入碎片管理器与商品信息队列 private MobilePagerAdapter(android.support.v4.app.FragmentManager fm , ArrayList<GoodsInfo> goodsList){ super(fm); mGoodsList = goodsList; } //获取指定位置的fragment @Override public Fragment getItem(int position) { return DynamicFragment.newInstance(position,mGoodsList.get(position).pic,mGoodsList.get(position).desc); } //获取碎片fragment的个数 @Override public int getCount() { return mGoodsList.size(); } //获得指定碎片页的标题文本 public CharSequence getPageTitle(int position){ return mGoodsList.get(position).name; } }
下面是动态注册的碎片代码:
package bean; import android.app.Fragment; import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.example.animator.highleveltools.R; /** * Created by animator on 2020/1/29. */ public class DynamicFragment extends Fragment { protected View mView;//声明一个视图对象 protected Context mContext;//声明一个上下文对象 private int mPosition;//位置序号 private int mImageId;//图片的资源编号 private String mDesc;//商品的文字描述 //获取该碎片的一个实例 public static DynamicFragment newInstance(int position,int image_id,String desc){ DynamicFragment fragment = new DynamicFragment();//创建该碎片的一个实例 Bundle bundle = new Bundle();//创建一个新包裹 bundle.putInt("position",position); bundle.putInt("image_id",image_id); bundle.putString("desc",desc); fragment.setArguments(bundle);//把包裹塞给碎片 return fragment; } //创建碎片视图 public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){ mContext = getActivity(); if(getArguments()!=null){//如果碎片携带有包裹 mPosition = getArguments().getInt("position"); mImageId = getArguments().getInt("image_id"); mDesc = getArguments().getString("desc"); } //根据布局文件fragment_dynamic.xml生成视图对象 mView = inflater.inflate(R.layout.fragment_dynamic,container,false); ImageView iv_pic = mView.findViewById(R.id.iv_pic); TextView tv_desc = (TextView) mView.findViewById(R.id.tv_desc); iv_pic.setImageResource(mImageId); tv_desc.setText(mDesc); return mView;//返回该碎片的视图对象 } }
下面是activity代码:
ArrayList<GoodsInfo> goodsList = GoodsInfo.getDefaultList(); //构建一个手机商品的碎片翻页适配器 MobilePagerAdapter adapter = new MobilePagerAdapter(getSupportFragmentManager(),goodsList); //从布局视图中获取名叫vp_content的翻页视图 ViewPager vp_content = findViewById(R.id.vp_content); //给vp_content设置手机商品的碎片适配器 vp_content.setAdapter(adapter); //设置vp_content默认显示第一个页面 vp_content.setCurrentItem(0);