Fragment进阶补充&viewpager
Fragment进阶补充&viewpager
关于Fragment传值
1.Activity给Fragment传值
Activity:
public class Activity extends AppCompatActivity {
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a_2_f);
editText = findViewById(R.id.et_id);
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.linear_layout_id,new ShowContextFragment());
fragmentTransaction.commit();
}
public void click(View view) {
//取到输入的值
String string = editText.getText().toString();
//创建fragment对象
ShowContextFragment showContextFragment = new ShowContextFragment();
//创建bundle
Bundle bundle = new Bundle();
bundle.putString("key",string);
//给fragment对象赋值
showContextFragment.setArguments(bundle);
//动态修改fragment
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.linear_layout_id,showContextFragment);
fragmentTransaction.commit();
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".A2FActivity">
<EditText
android:id="@+id/et_id"
android:hint="来啊,传点啥吧!"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我试试"
android:onClick="click"
/>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/linear_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</LinearLayout>
Fragment:
public class ShowContextFragment extends Fragment {
private TextView textView;
public ShowContextFragment() {
// Required empty public constructor
}
//现在text里面的值是"hello_blank_fragment",思路就是拿到控件,重新赋值即可.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_show_context, container, false);
//1 拿控件
textView = inflate.findViewById(R.id.context_tv_id);
//2 给控件赋值
Bundle arguments = getArguments();
if(arguments != null){ //第一次启动一定为null,所以要判断一下
String key = arguments.getString("key");
textView.setText(key);
}
return inflate;
}
}
2.Fragment给Activity传值
第一种:
在Activity中调用getFragmentManager()得到fragmentManager,,调用findFragmentByTag(tag)或者通过findFragmentById(id)
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
第二种:
通过回调的方式,定义一个接口(可以在Fragment类中定义),接口中有一个空的方法,在fragment中需要的时候调用接口的方法,值可以作为参数放在这个方法中,然后让Activity实现这个接口,必然会重写这个方法,这样值就传到了Activity中
大白话,就是java的父类引用指向了子类对象
public class ShowTitleFragment extends Fragment {
private EditText editText;
private Button button;
private MyListener listener;
public ShowTitleFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//拿到与当前fragment关联的Activity.
listener = (MyListener) getActivity();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_show_title, container, false);
//取到所有控件
editText = inflate.findViewById(R.id.fm_title_et_id);
button = inflate.findViewById(R.id.fm_title_button_id);
//点击事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String string = editText.getText().toString();
if(string != null){
//注意了.这里是父类引用指向了子类对象,其实是activity中的sendmessage方法在执行.
listener.sendMessage(string);
}
}
});
//返回fragment中的布局视图
return inflate;
}
//自定义的接口
public interface MyListener{
void sendMessage(String string);
}
}
3.Fragment给Fragment传值
三种方式:
第一种:
动态创建的fragment通过findFragmentByTag得到另一个的Fragment的对象,这样就可以调用另一个的方法了。
静态创建的fragment通过findFragmentById得到另一个的Fragment的对象,这样就可以调用另一个的方法了。
第二种:
通过接口回调的方式。
public class BlankFragment extends Fragment {
private Button btn;
private EditText msg;
public BlankFragment() {
// Required empty public constructor
}
public interface MyListener{
void sendmessage(String s);
}
public MyListener myListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myListener = (MyListener) getActivity().getSupportFragmentManager().findFragmentById(R.id.right);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflate = inflater.inflate(R.layout.fragment_blank, container, false);
btn = inflate.findViewById(R.id.btn);
msg = inflate.findViewById(R.id.msg);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String s = msg.getText().toString();
// TextView show = getActivity().findViewById(R.id.show);
// show.setText(s);
if (s!=null){
myListener.sendmessage(s);
}
}
});
return inflate;
}
}
第三种:
通过setArguments,getArguments的方式。
Viewpager
Viewpager是什么?
Viewpager,视图翻页工具,提供了多页面切换的效果。Android 3.0后引入的一个UI控件,位于v4包中。低版本使用需要导入v4包,但是现在我们开发的APP一般不再兼容3.0及以下的系统版本,另外现在大多数使用Android studio进行开发,默认导入v7包,v7包含了v4,所以不用导包,越来越方便了。
Viewpager使用起来就是我们通过创建adapter给它填充多个view,左右滑动时,切换不同的view。Google官方是建议我们使用Fragment来填充ViewPager的,这样 可以更加方便的生成每个Page,以及管理每个Page的生命周期。
ViewPager 直接继承了 ViewGroup,所有它是一个容器类,可以在其中添加其他的 view 类。
ViewPager 需要一个 PagerAdapter 适配器类给它提供数据。
ViewPager 经常和 Fragment 一起使用,并且提供了专门的 FragmentPagerAdapter 和 FragmentStatePagerAdapter 类供 Fragment 中的 ViewPager 使用
用法类似ListView,区别是ListView以每行为条目,而ViewPager是以
使用步骤
1.先在xml中引入
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ViewPagerActivity">
<android.support.v4.view.ViewPager
android:id="@+id/vp_id"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
2.在layout文件文件夹中,创建一个viewPager的布局文件作为viewpager的视图
3.创建适配器,继承PagerAdapte
适配器中重写的方法详解:
getCount( ):获得viewpager中有多少个view
destroyItem( ):移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保 在finishUpdate(viewGroup)返回时视图能够被移除。
instantiateItem( ):①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来 ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了, 当然你也可以自定义自己的key,但是key和每个view要一一对应的关系
isViewFromObject( ):判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是 代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写 return view == object
4.按照需求完善适配中的方法
public class ViewPagerAdapter extends PagerAdapter {
private Context context;
private List<String> mData;
public ViewPagerAdapter(Context context, List<String> mData) {
this.context = context;
this.mData = mData;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view == o;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//加载vp的布局
View inflate = View.inflate(context, R.layout.vp_layout, null);
//给布局中的控件赋值
TextView textView = inflate.findViewById(R.id.vp_tv_id);
textView.setText(mData.get(position));
//添加一个布局
container.addView(inflate);
//返回布局
return inflate;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// super.destroyItem(container, position, object);这一句要删除,否则报错
container.removeView((View) object);
}
}
Activity
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager vpId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉自带的bar
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_veiw_pager);
//找到vp
vpId = findViewById(R.id.vp_id);
//初始化数据
List<String> list = new ArrayList<>();
for (int i = 0; i < 4; i++) {
list.add("第"+i+"个View");
}
//设置adapter
vpId.setAdapter(new ViewPagerAdapter(this,list));
}
}
自动翻页
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewpager);
final List<String> list = new ArrayList<>();
handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 100) {
viewPager.setCurrentItem(index);
index++;
if (index == list.size()) {
index = 0;
}
}
}
};
for (int i = 0; i < 4; i++) {
list.add("这是第"+(i+1)+"个View");
}
viewPager.setAdapter(new pagerAdpater(this,list));
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.sendEmptyMessage(100);
}
},0,1000);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Toast.makeText(MainActivity.this, "当前页数为"+(position+1), Toast.LENGTH_SHORT).show();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
##ViewPager与Fragment结合使用
Activity:
public class MainActivity extends AppCompatActivity {
private List<Fragment> list = new ArrayList<>();
private ViewPager vp;
private Bundle bundle;
private Handler handler;
private int index = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vp = findViewById(R.id.vp);
for (int i = 0; i <5 ; i++) {
BlankFragment blankFragment = new BlankFragment();
Bundle bundle = new Bundle();
bundle.putString("key",i+" ");
blankFragment.setArguments(bundle);
list.add(blankFragment);
}
handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 100) {
vp.setCurrentItem(index);
index++;
if (index == list.size()) {
index = 0;
}
}
}
};
vp.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return list.get(position);
}
@Override
public int getCount() {
return list.size();
}
});
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.sendEmptyMessage(100);
}
},0,3000);
}
}
上一篇: 从注释跳转到指定方法,从注释跳转到指定类
推荐阅读
-
Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版
-
详解Android 在 ViewPager 中使用 Fragment 的懒加载
-
viewPager+fragment刷新缓存fragment的方法
-
Viewpager+Fragment 跳转Activity报错android.os.TransactionTooLargeException: data parcel size xxxxx bytes
-
Android使用ViewPager快速切换Fragment时卡顿的优化方案
-
Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题
-
TabLayout和ViewPager、Fragment的滑动页面的实现
-
安卓底部导航栏的实现以及用TabLayout+ViewPager+Fragment实现页面滑动切换
-
ViewPager中切换界面Fragment被销毁的问题
-
Android ViewPager + Fragment实现滑动页面