ViewPager动态添加或删除Fragment刷新空白问题处理,及Fragment数据传递简介

很久没更博客了,因为自己前段时间一直在独立开发项目、、、但这不能成为懒惰的理由,自省3秒···  好了废话不多说,开始撸码

(以后都会采取先Java展示,后kotlin展示形式,小伙伴们可以各取所需)

之前一直都是很基础的固定Fragment个数与ViewPager搭配使用,在项目中要求动态添加Fragment展示界面,但是却遇到了刷新空白,或者刷新不完全的问题出现,借此自写个demo以供参考

效果入下:

解释下为什么会刷新失败:原因是Fragment在adapter中会形成缓存,在每次创建前都会去对比一下此Fragment是否存在,这就是造成刷新不是我们预想的情况出现

步骤如下:

1、新建类并继承Fragment,接受数据完善布局

2、创建类并继承 FragmentStatePagerAdapter ,重写其内部方法 ,并重写getItemPosition()将返回值设置为PagerAdapter.POSITION_NONE(此处解决刷新问题)

3、程序中实现数据源、viewpager及其adapter配置即可

代码如下:

1、新建类并继承Fragment,接受数据完善布局

package com.leixiansheng.test;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by Leixiansheng on 2018/12/10.
 */

public class MyFragment extends Fragment {

	public static Fragment newInstance(String content) {
		MyFragment fragment = new MyFragment();
		Bundle bundle = new Bundle();
		bundle.putString("content", content);
		fragment.setArguments(bundle);
		return fragment;
	}

	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		String content = getArguments().getString("content");
		View view = inflater.inflate(R.layout.fragment_base, container, false);
		TextView textView = (TextView) view.findViewById(R.id.tvContent);
		textView.setText(content);
		return view;
	}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tvContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="20sp"
        android:textColor="@color/colorAccent"/>
</RelativeLayout>

2、创建类并继承 FragmentStatePagerAdapter ,重写其内部方法

3、程序中实现数据源、viewpager及其adapter配置即可

package com.leixiansheng.test;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

	private List<String> contents = new ArrayList<>();
	private MyFragmentPagerAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		contents.add("one");
		contents.add("two");
		contents.add("three");

		ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
		Button add = (Button) findViewById(R.id.btnAdd);
		Button delete = (Button) findViewById(R.id.btnDelete);
		adapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
		viewPager.setAdapter(adapter);

		add.setOnClickListener(this);
		delete.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			case R.id.btnAdd:
				contents.add("add");
				adapter.notifyDataSetChanged();
				break;
			case R.id.btnDelete:
				if (contents.size() > 0) {
					contents.remove(contents.size() - 1);
					adapter.notifyDataSetChanged();
				}
				break;
			default:
				break;
		}
	}

	class MyFragmentPagerAdapter extends FragmentStatePagerAdapter{

		private MyFragmentPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int position) {
			return MyFragment.newInstance(contents.get(position));
		}

		@Override
		public int getCount() {
			return contents.size();
		}

		@Override
		public int getItemPosition(Object object) {
			return PagerAdapter.POSITION_NONE;
		}
	}
}

Kotlin代码如下(与国际接轨嘛,啊哈哈)

package com.leixiansheng.kotlintest

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.TextView
import kotlinx.android.synthetic.main.fragment_base.view.*

/**
 * Created by Leixiansheng on 2018/11/23.
 */
class MyFragment : Fragment() {

    fun newInstance(text:String):MyFragment{
        val fragment = MyFragment()
        val bundle = Bundle()
        bundle.putString("content", text)
        fragment.arguments = bundle
        return fragment
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {
        val content = arguments.getString("content")

        val view = inflater!!.inflate(R.layout.fragment_base, container, false)
        val tvContent: TextView = view.tvContent
        tvContent.text = content
        return view
    }

}
package com.leixiansheng.kotlintest

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentStatePagerAdapter
import android.support.v4.view.PagerAdapter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    val list = mutableListOf<String>("one", "two", "three")


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val adapter = MyFragmentPagerAdapter(supportFragmentManager, list)
        viewPager.adapter = adapter

        add.setOnClickListener {
            list.add("add")
            adapter.notifyDataSetChanged()
        }

        delete.setOnClickListener {
            if (list.size > 0) {
                list.removeAt(list.size-1)
                adapter.notifyDataSetChanged()
            }
        }

    }

    class MyFragmentPagerAdapter(fm:FragmentManager,val list: List<String>) : FragmentStatePagerAdapter(fm){

        /**
         * Return the Fragment associated with a specified position.
         */
        override fun getItem(position: Int): Fragment {
            return MyFragment().newInstance(list[position])
        }

        /**
         * Return the number of views available.
         */
        override fun getCount(): Int {
            return list.size
        }

        /**
         * 必须重写此方法才能完全刷新
         */
        override fun getItemPosition(`object`: Any?): Int {
            return PagerAdapter.POSITION_NONE
        }
    }
}

还有一种处理情况继承的是  FragmentPagerAdapter时:

在Adapter中添加一个方法,手动移除存在的Fragment

private void setFragments(List<OverlapFragment> fragments) {
			FragmentManager fm = getFragmentManager();

			if (mFragments != null) {
				FragmentTransaction ft = fm.beginTransaction();
				for (Fragment f : fragments) {
					ft.remove(f);
				}
				ft.commit();
				ft = null;
				fm.executePendingTransactions();
			}
			mFragments = fragments;
			notifyDataSetChanged();
		}

猜你喜欢

转载自blog.csdn.net/Mr_Leixiansheng/article/details/84391695