当另一个片段中的数据发生更改时,如何刷新一个片段中的 RecyclerView
Posted
技术标签:
【中文标题】当另一个片段中的数据发生更改时,如何刷新一个片段中的 RecyclerView【英文标题】:How to refresh RecyclerView in one fragment when data changed in another fragment 【发布时间】:2017-03-24 00:59:28 【问题描述】:数据提交成功后,如何将本地数据库中的数据刷新到RecyclerView?我使用应用程序上的选项卡。 2nd-Tab
函数提交数据,如果成功,数据将存储在localDB
。
localDB
上的数据我将在3rd-Tab
上展示。
但是会发生什么,我必须滑动1st-Tab
,然后滑动到2nd-Tab
,然后再滑动到我的localDB
上的新3rd-Tab
数据成功显示。
如果2nd-Tab我提交数据,然后我刷到3rd-Tab
,数据将不会出现在数据列表中。
如何让数据直接显示而不需要滑动到第一个1st-Tab
然后到2nd-Tab
和3rd-Tab
?
MainActivity:
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import com.bertho.gmyl.fragments.EngagedFragment;
import com.bertho.gmyl.fragments.RequestFragment;
import com.bertho.gmyl.fragments.SigninFragment;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
private static final String TAG = MainActivity.class.getSimpleName();
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.engine_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private void setupViewPager(ViewPager viewPager)
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new SigninFragment(), "SIGN-IN");
adapter.addFrag(new EngagedFragment(), "ENGAGED ID");
adapter.addFrag(new RequestFragment(), "LOCATION");
viewPager.setAdapter(adapter);
class ViewPagerAdapter extends FragmentPagerAdapter
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
super(manager);
@Override
public Fragment getItem(int position)
return mFragmentList.get(position);
@Override
public int getCount()
return mFragmentList.size();
public void addFrag(Fragment fragment, String title)
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
@Override
public CharSequence getPageTitle(int position)
return mFragmentTitleList.get(position);
EngagedFragment(2nd-Tab)表单来保存数据
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.bertho.gmyl.R;
import com.bertho.gmyl.model.Engaged;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.bertho.gmyl.realm.RealmHelper;
public class EngagedFragment extends Fragment implements View.OnClickListener
private static final String TAG = EngagedFragment.class.getSimpleName();
private EditText nama, email, nohp;
private Button btnSaveConnection;
private DatabaseReference mFirebaseDatabase;
private FirebaseDatabase mFirebaseInstance;
private RelativeLayout mRoot;
private View rootView;
private String userId;
private TextView lblNama, lblEmail, lblNohp;
private RelativeLayout relativeLayout;
private RealmHelper realmHelper;
public EngagedFragment()
// Required empty public constructor
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.fragment_engaged, container, false);
realmHelper = new RealmHelper(getActivity());
String appName = getResources().getString(R.string.app_name);
loadLocalDB();
nama = (EditText) rootView.findViewById(R.id.txtName);
email = (EditText) rootView.findViewById(R.id.txtEmail);
nohp = (EditText) rootView.findViewById(R.id.txtNoHp);
lblNama = (TextView) rootView.findViewById(R.id.lblNameval);
lblEmail = (TextView) rootView.findViewById(R.id.lblEmailval);
lblNohp = (TextView) rootView.findViewById(R.id.lblNohpval);
relativeLayout = (RelativeLayout) rootView.findViewById(R.id.panelLabelDetail);
btnSaveConnection = (Button) rootView.findViewById(R.id.btnEngaged);
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseDatabase = mFirebaseInstance.getReference("tbl_engaged");
mFirebaseInstance.getReference("titleapp").setValue(appName);
mFirebaseInstance.getReference("titleapp").addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
Log.e(TAG, "TITLE UPDATED FROM FIREBASE");
String appTitle = dataSnapshot.getValue(String.class);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(appTitle);
@Override
public void onCancelled(DatabaseError error)
Log.e(TAG, "FAILED TO READ TITLE FROM FIREBASE.", error.toException());
);
btnSaveConnection.setOnClickListener(this);
return rootView;
private void showSnack(String notify)
mRoot = (RelativeLayout) rootView.findViewById(R.id.frag_engaged);
Snackbar snackbar = Snackbar.make(mRoot, notify, Snackbar.LENGTH_LONG);
snackbar.show();
public void onClick(View v)
if(v.getId() == R.id.btnEngaged)
String txtName = nama.getText().toString();
String txtEmail = email.getText().toString();
String txtNo = nohp.getText().toString();
if(txtName.equals("") || txtName.isEmpty())
showSnack("Name must filled");
nama.requestFocus();
else if (txtEmail.equals("") || txtEmail.isEmpty())
showSnack("Email must filled");
email.requestFocus();
else if (txtNo.equals("") || txtNo.isEmpty())
showSnack("No.HP must filled");
nohp.requestFocus();
else
createUser(txtName, txtEmail, txtNo);
saveToLocalDB(txtName, txtEmail, txtNo);
private void saveToLocalDB(String txtName, String txtEmail, String txtNo)
realmHelper.addEngaged(txtName, txtEmail, txtNo);
private void loadLocalDB()
realmHelper.getAllData();
private void createUser(String name, String email, String nohp)
userId = mFirebaseDatabase.push().getKey();
Engaged user = new Engaged(name, email, nohp);
mFirebaseDatabase.child(userId).setValue(user);
addUserChangeListener();
private void addUserChangeListener()
mFirebaseDatabase.child(userId).addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
Engaged user = dataSnapshot.getValue(Engaged.class);
if (user == null)
Log.e(TAG, "ENGAGED DATA IS NULL");
return;
Log.e(TAG, "ENGAGED DATA IS CHANGED!" + user.name + ", " + user.email);
lblNama.setText(user.name);
lblEmail.setText(user.email);
lblNohp.setText(user.nohp);
//relativeLayout.setVisibility(View.VISIBLE);
nama.setText("");
email.setText("");
nohp.setText("");
@Override
public void onCancelled(DatabaseError error)
// Failed to read value
Log.e(TAG, "FAILED TO READ USER", error.toException());
);
RequestFragment (3rd-Tab) 显示 localDB
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.bertho.gmyl.R;
import com.bertho.gmyl.adapter.AdapterEngaged;
import com.bertho.gmyl.model.ModelEngaged;
import com.bertho.gmyl.realm.RealmHelper;
import java.util.ArrayList;
public class RequestFragment extends Fragment
private static final String TAG = "RequestFragment";
private RecyclerView recyclerView;
private View rootView;
private ArrayList<ModelEngaged> data;
private RealmHelper helper;
public RequestFragment()
// Required empty public constructor
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
rootView = inflater.inflate(R.layout.fragment_request, container, false);
data = new ArrayList<>();
helper = new RealmHelper(getActivity());
recyclerView = (RecyclerView) rootView.findViewById(R.id.rvArticle);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
setRecyclerView();
return rootView;
public void setRecyclerView()
try
data = helper.findAllArticle();
catch (Exception e)
e.printStackTrace();
AdapterEngaged adapter = new AdapterEngaged(data, new AdapterEngaged.OnItemClickListener()
@Override
public void onClick(ModelEngaged item)
Toast.makeText(getContext(), "LIST CLICKED", Toast.LENGTH_LONG).show();
);
recyclerView.setAdapter(adapter);
@Override
public void onResume()
super.onResume();
try
data = helper.findAllArticle();
catch (Exception e)
e.printStackTrace();
setRecyclerView();
一切都很顺利,只是希望表单提交的时候可以显示数据,可以在3rd-Tab上直接查看
【问题讨论】:
试试这个,在活动中使用一个接口,每当您在第二个选项卡中提交时设置回调,并在活动中的回调方法中重新加载第三个片段的列表 Viewpager初始化后尝试在mainactivity oncreate方法中加入这一行:ViewPager.setOffscreenPageLimit(3); 对viewPager.setOffscreenPageLimit();
无效
@BerthoJoris 你解决了这个问题吗?
还没有......我还在尝试这个解决方案***.com/questions/20412379/…
【参考方案1】:
试试这个,
在 EngagedFragment 中创建接口 说,
public interface SubmitListener
void onSubmit();
private SubmitListener onSubmitListener;
public void setSubmitListener(SubmitListener onSubmitListener)
this.onSubmitListener = onSubmitListener;
public SubmitListener getOnSubmitListener()
return onSubmitListener;
在 saveToLocalDB(...) 方法中
打电话
onSubmitListener.onSubmit();
在 MainActivity:
1) 更新以下语句:
public class MainActivity extends AppCompatActivity implements EngagedFragment.SubmitListener
2) 将您的 ViewPagerAdapter 适配器; 变量设为全局变量;
添加片段时:
EngagedFragment engagedFrag = new EngagedFragment();
adapter.addFrag(engagedFrag, "ENGAGED ID");
...
viewPager.setAdapter(adapter);
3) 设置适配器后添加此项
engagedFrag.setSubmitListener(this);
4) 重写 onSubmit() 方法并在该方法中尝试以下代码
if(viewPager != null)
if(adapter != null)
Fragment fragment = adapter.getItem(2);
if(fragment != null)
RequestFragment requestFragment = (RequestFragment) fragment;
requestFragment.setRecyclerView();
【讨论】:
Hai @Raghavendra,当我尝试您的代码时,我发现单击按钮保存时强制关闭。错误java.lang.NullPointerException: Attempt to invoke interface method 'void com.bertho.gmyl.fragments.EngagedFragment$SubmitListener.onSubmit()' on a null object reference
也许我错过了什么。但是,当我检查时,数据已保存。只强制关闭我的应用程序。这是 MainActivity :pastebin.com/mnMVzkjr 这是 EngagedFragment :pastebin.com/bWgSGmuk
是啊.....完美的作品..... :) 谢谢@Raghavendra ...顺便说一句,如果我有另一个选项卡,比如说第五个选项卡,我必须再次覆盖 onSubmit 方法中的代码?
@BerthoJoris 很高兴!这有帮助。我没有得到qsn伙计。你能改写一下你想在第 5 个标签中做什么吗?
谢谢@Raghavendra ...它运行良好。非常感谢【参考方案2】:
试试这个
mViewPager.setOffscreenPageLimit(0);
如果这没有帮助,请检查下面的问题:
fragment refresh On Swip
关于:mViewPager.setOffscreenPageLimit(0);
这可能不起作用,因为我在@commonware 的答案之一中找到了以下内容:-
"ViewPager 是否需要至少 1 个屏幕外页面
Yes
。如果我正确阅读了源代码,您应该会在 LogCat 中收到关于此的警告,例如:
Requested offscreen page limit 0 too small; defaulting to 1"
【讨论】:
是的..不适用于viewPager.setOffscreenPageLimit(0);
你试过链接答案了吗?
还没有……但我会在这之后尝试以上是关于当另一个片段中的数据发生更改时,如何刷新一个片段中的 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章
当sqlite android片段中的数据更改或删除时如何刷新recyclerview?