[英]Reset RecyclerView adapter from another Fragment
我有一个包含RecyclerView的Fragment。 我正在尝试在RecyclerView上实现过滤器。 过滤器UI将打开一个新的片段对话框,用户将在其中输入值。 一旦用户点击片段对话框中的搜索按钮 ,该值应返回到RecyclerView片段,并且应清除视图中的现有数据。 我想用我将从服务器获取的新数据集重新填充RecyclerView。 我的问题是,我在RecyclerView Fragment中有一个名为resetAdapterDetails()
的方法,如果从RecyclerView Fragment本身调用,它会按预期工作。 但是,当我尝试从Fragment Dialog调用相同的方法时,我得到一个例外:
transactionList.clear(); --> is trying to clear a list which is null
虽然数据在RecyclerView中仍然可见。
RecyclerView片段 :
public class TransactionHistoryFragment extends Fragment implements SearchView.OnQueryTextListener, DateRangePickerFragment.OnDateRangeSelectedListener{
private RecyclerView recyclerview;
private TransactionHistoryAdapter adapter;
private List<Transaction> transactionList;
public TransactionHistoryFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_transaction_history, container, false);
recyclerview = (RecyclerView) view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(layoutManager);
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
getTransactionHistory("");
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.transactions_history_menu, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.filter_date:
FragmentManager fmDate = getActivity().getFragmentManager();
DateRangePickerFragment dialogFragmentDate = DateRangePickerFragment.newInstance(this, true);
dialogFragmentDate.show(fmDate, "Sample Fragment");
return true;
case R.id.filter_mobile:
FragmentManager fmMobile = getActivity().getFragmentManager();
SearchMobileFragment dialogFragmentMobile = new SearchMobileFragment ();
dialogFragmentMobile.show(fmMobile, "Sample Fragment");
//resetAdapterDetails();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onQueryTextChange(String newText) {
final List<Transaction> filteredModelList = filter(transactionList, newText);
adapter.setFilter(filteredModelList);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
//for filtering the list
private List<Transaction> filter(List<Transaction> models, String query) {
query = query.toLowerCase();final List<Transaction> filteredModelList = new ArrayList<>();
for (Transaction model : models) {
final String text = model.getTxnStatus().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
//for populating the list
private void getTransactionHistory(String agentId){
GetTransactionHistoryTask task = new GetTransactionHistoryTask("agent1", "password");
task.getTransactionsByAgent("OU23","OU230000000123456789").subscribe(transactionHistoryResponse -> {
if(transactionHistoryResponse != null && transactionHistoryResponse.getTransactions() != null && transactionHistoryResponse.getTransactions().size() > 0 && transactionHistoryResponse.getErrors().size() == 0){
transactionList = transactionHistoryResponse.getTransactions();
adapter = new TransactionHistoryAdapter(transactionList);
recyclerview.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
recyclerview.setAdapter(adapter);
onClickListnerRecyclerView();
}
else{
}
}, e -> e.printStackTrace());
}
private void onClickListnerRecyclerView() {
recyclerview.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
try {
final Transaction transactionModel= (Transaction) adapter.getObjectAt(position);
Intent i = new Intent(getActivity(), TransactionDetailsActivity.class);
i.putExtra("transaction_object",transactionModel);
startActivity(i);
}
catch (Exception e){
Log.e("List issue", e.toString());
}
}
})
);
}
@Override
public void onDateRangeSelected(int startDay, int startMonth, int startYear, int endDay, int endMonth, int endYear) {
}
public void fetchDateRange(String startDate, String endDate) {
Log.e("DateRange",startDate + "\n" + endDate);
}
public void fetchMobileNumber(String mobileNumber) {
Log.e("Mobile",mobileNumber);
resetAdapterDetails();
}
public boolean resetAdapterDetails(){
try {
transactionList.clear();
adapter.notifyDataSetChanged();
recyclerview.setAdapter(adapter);
} catch (Exception e) {
Log.e("Reset Error", ""+e.getMessage());
}
return true;
}
}
对话片段 :
public class SearchMobileFragment extends DialogFragment {
EditText mMobileNumberEditText;
Button search_button;
public SearchMobileFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_search_mobile, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mMobileNumberEditText = (EditText) view.findViewById(R.id.mobile_number_editText);
search_button = (Button) view.findViewById(R.id.search_button);
search_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
TransactionHistoryFragment obj = new TransactionHistoryFragment();
obj.fetchMobileNumber(mMobileNumberEditText.getText().toString());
}
});
}
}
所述fetchMobileNumber()
在TransactionHistoryFragment(RecyclerView片段)的方法是通过称为fetchMobileNumber()
其从所述SearchMobileFragment(对话片段)调用的方法。
我哪里错了? 为什么是transactionList.clear();
抛出空指针异常?
您收到此问题是因为您在SearchMobileFragment中创建了新的TransactionHistoryFragment实例search_button。 这使得它的所有变量都为null并再次初始化它,这里您的transactionList变为null。
您也可以通过不同的方式轻松实现同样的目标。 作为SearchogobileFragment作为DialogFragment的位置,您可以将其作为Activity并从TransactionHistoryFragment中将其作为startActivityForResult启动,并实现onActivityResult回调以进行fiteration。
但是现在你可以用不同的方式管理它:
第一种方式:正如您在DialogFragment中所做的那样
search_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
/*TransactionHistoryFragment obj = new TransactionHistoryFragment();
obj.fetchMobileNumber(mMobileNumberEditText.getText().toString());*/
}
});
不要在这里调用fetchMobileNumber,在您的TransactionHistoryFragment的onResume中,您应该调用它。 在单击search_button时,将过滤器数据保存到SharedPreferences,并在TransactionHistoryFragment的onResume中使用它进行过滤,然后在此片段的SharedPreferences onPause中清除此保存的数据。
你应该删除
transactionList.clear();
来自TransactionHistoryFragment中的resetAdapterDetails()的代码,因为在搜索过滤器之后,您将获得更新的事务列表,该事务列表已经传递给适配器,然后强制不需要清除它。 或者在清除它之前进行检查:
if(transactionList!=null){
transactionList.clear();
}
第二种方式:使用BroadcastReceiver可以实现同样的目的。 在TransactionHistoryFragment中注册一个接收者,从SearchMobileFragment注册sendBroadcast。 在onHceive的TransactionHistoryFragment中执行过滤过程。
我以不同的方式解决了上述问题。 在Dialog Fragment中,我实现了一个View.OnClickListener
并创建了一个Interface来从RecyclerView Fragment初始化它。 我在下面发布完整的源代码; SearchMobileFragment现在看起来像:
public class SearchMobileFragment extends DialogFragment implements View.OnClickListener{
private OnMobileNumberSelectedListener onMobileNumberSelectedListener;
EditText mMobileNumberEditText;
Button mSearchButton;
public SearchMobileFragment() {
// Required empty public constructor
}
public static SearchMobileFragment newInstance(OnMobileNumberSelectedListener callback) {
SearchMobileFragment searchMobileFragment = new SearchMobileFragment();
searchMobileFragment.initialize(callback);
return searchMobileFragment;
}
public void initialize(OnMobileNumberSelectedListener callback) {
onMobileNumberSelectedListener = callback;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_search_mobile, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mMobileNumberEditText = (EditText) root.findViewById(R.id.mobile_number_editText);
mSearchButton = (Button) root.findViewById(R.id.search_button);
mSearchButton.setOnClickListener(this);
return root;
}
@Override
public void onStart() {
super.onStart();
if (getDialog() == null)
return;
getDialog().getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
}
public void setOnMobileNumberSelectedListener(OnMobileNumberSelectedListener callback) {
this.onMobileNumberSelectedListener = callback;
}
@Override
public void onClick(View v) {
dismiss();
onMobileNumberSelectedListener.onMobileNumberSelected(mMobileNumberEditText.getText().toString());
}
public interface OnMobileNumberSelectedListener {
void onMobileNumberSelected(String mobileNumber);
}
}
RecyclerView片段修改:
public class TransactionHistoryFragment extends Fragment implements SearchView.OnQueryTextListener,
DateRangePickerFragment.OnDateRangeSelectedListener, SearchMobileFragment.OnMobileNumberSelectedListener{
private RecyclerView recyclerview;
private TransactionHistoryAdapter adapter;
private List<Transaction> transactionList;
SearchView search;
public static final String TIMERANGEPICKER_TAG = "timerangepicker";
public TransactionHistoryFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_transaction_history, container, false);
recyclerview = (RecyclerView) view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(layoutManager);
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
getTransactionHistory();
}
@Override
public void onResume() {
Log.e("onResumeTHF","invoked");
super.onResume();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.transactions_history_menu, menu);
search = (SearchView) menu.findItem(R.id.action_search).getActionView();
search.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.filter_date:
FragmentManager fmDate = getActivity().getFragmentManager();
DateRangePickerFragment dialogFragmentDate = DateRangePickerFragment.newInstance(this, true);
dialogFragmentDate.show(fmDate, "Sample Fragment");
return true;
case R.id.filter_mobile:
FragmentManager fmMobile = getActivity().getFragmentManager();
SearchMobileFragment dialogFragmentMobile = SearchMobileFragment.newInstance(this);
dialogFragmentMobile.show(fmMobile, "Sample Fragment");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onQueryTextChange(String newText) {
Log.e("newText",newText);
final List<Transaction> filteredModelList = filter(transactionList, newText);
adapter.setFilter(filteredModelList);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public void onMobileNumberSelected(String mobileNumber) {
Log.e("mobileNumber",mobileNumber);
resetAdapterDetails();
}
public boolean resetAdapterDetails(){
try {
transactionList.clear();
adapter.notifyDataSetChanged();
recyclerview.setAdapter(adapter);
} catch (Exception e) {
Log.e("Reset Error", ""+e.getMessage());
}
return true;
}
}
快乐的编码!
空指针异常是因为当您使用new
onViewCreated
创建新的TransactionHistoryFragment
未调用,因此transactionList
永远不会被初始化。 您可以为列表创建一个setter,或将其作为构造函数传递给片段以解决此问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.