[英]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.