很久没更博客了,因为自己前段时间一直在独立开发项目、、、但这不能成为懒惰的理由,自省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();
}