簡體   English   中英

從另一個片段重置RecyclerView適配器

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM