欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Fragment进阶补充&viewpager

程序员文章站 2022-06-09 15:53:36
...

关于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);
    }
}

相关标签: ViewPager