2017-09-03 39 views
0

我有CardView項目的RecyclerView列表。然後,我使用一個簡單的過濾器方法和SearchView小部件來過濾列表。當我然後點擊過濾的CardView來啓動CardViewDetails活動時,UI將顯示來自原始列表的CardView而不是過濾的列表。例如,我在原始列表中列出了20個項目。當我輸入一個搜索約束時,過濾後的List正確顯示了RecyclerView中的三個CardView。當我單擊列表中的第三個CardView時,UI會從原始列表中返回第三個CardView,而不是從過濾列表中返回第三個CardView。我在這裏錯過了什麼?RecyclerView:已過濾列表中的錯誤位置

Adapter: 

public class MyRecylerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

private List<ListItem> mListItems, filteredList; 
Context mContext; 
private RecyclerItemClickListener recyclerItemClickListener; 
private RecyclerView mRecyclerView; 
/**********************************************************/ 
private String searchString = ""; 
/**********************************************************/ 

public MyRecylerAdapter(Context context, List<ListItem> listItems) { 
    this.mContext = context; 
    this.mListItems = listItems; 
    this.filteredList = new ArrayList<>(); 
    this.filteredList.addAll(this.mListItems); 
} 

// RecyclerItemClickListener is the public interface file used to reach the MainActivity 
public void setOnItemClickListener(RecyclerItemClickListener recyclerItemClickListener) { 
    this.recyclerItemClickListener = recyclerItemClickListener; 
} 

// Get the Item's position. 
public ListItem getItem(int position) { 
    return filteredList.get(position); 
} 

@Override 
public int getItemCount() { 
    if (filteredList.size() >0) { 
     return filteredList.size(); 
    } 
    else { 
     return mListItems.size(); 
    } 
} 

public void setFilter(List<ListItem> listItems, String searchString) { 
    // Note: the String is to get s.toString() from the Main Activity SearchView. 
    filteredList = new ArrayList<>(); 
    filteredList.addAll(listItems); 
    this.searchString = searchString; 
    notifyDataSetChanged(); 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false); 
    final ItemHolder itemHolder = new ItemHolder(view); 

     // Attach a Click listener to the items's (row) view. 
     // itemView is from the ItemHolder() below. 
     // onItemClick is the click method in MainActivity. 
     itemHolder.itemView.setOnClickListener(new View.OnClickListener() {     
      @Override 
      public void onClick(View view) { 

       int adapterPos = itemHolder.getAdapterPosition(); // get the item position.      
       if (adapterPos != RecyclerView.NO_POSITION) { 
        if (recyclerItemClickListener != null) { 
         // pass the item to the Main Activity 
         // through the RecyclerItemClickListener file and its 
         // public interface. 
         recyclerItemClickListener.onItemClick(itemHolder.itemView,adapterPos); 
        } 
       } 
      } 
     });    
    return itemHolder; 
} 

private static class ItemHolder extends RecyclerView.ViewHolder { 

    private TextView cardBlankText2; 

    private ItemHolder(View itemView) { 
     super(itemView); 

     cardBlankText2 = (TextView) itemView.findViewById(R.id.cardBlankText2);    
} 

public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { 

    final ListItem listItem = filteredList.get(position); 
    final ItemHolder itemHolder = (ItemHolder) holder; 

    itemHolder.cardBlankText2.setText(listItem.getTodo()); 
} 

Activity: 

public class MainActivity extends AppCompatActivity implements 
    RecyclerItemClickListener { 

private List<ListItem> allList = new ArrayList<>(); 
private RecyclerView mRecyclerView; 
private SQLiteDB sqLiteDB; 
private MyRecylerAdapter adapter;  
private CardView cardview; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    sqLiteDB = SQLiteDB.getInstance(this);   
    mRecyclerView = (RecyclerView)findViewById(R.id.list_recyclerview);   
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);   
    mRecyclerView.setLayoutManager(layoutManager); 
    allList = sqLiteDB.getAllDBItems(); 

    adapter = new MyRecylerAdapter(this, allList); 
    adapter.setOnItemClickListener(this); 
    mRecyclerView.setAdapter(adapter); 
} 

@Override 
public void onItemClick(View view, int position) { 
    cardview = (CardView) view; 
    cardview.setEnabled(false); 

    // Create a new intent to send data from this MainActivity to the CardViewDetails 
    // Activity. 
    Intent intent = new Intent(this,CardViewDetails.class); 
    ListItem listItem = adapter.getItem(position); 
    // Add the item object to the Intent. The item object can be used because the 
    // model class implements Parcelable so it holds all of the getters 
    // that can be snagged in the next Activity with the 
    // getParcelableExtra method. 
    intent.putExtra("item",listItem); 
    intent.putExtra("position",position); 
    startActivity(intent); 
    finish(); 
} 

// SearchView 
final EditText mSearchEditText = (EditText) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text); 

    mSearchEditText.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 

     } 

     @Override 
     public void afterTextChanged(Editable s) { 

      final ArrayList<ListItem> filteredModelList = filter(allList, s.toString()); 

       if (!mSearchView.isIconified() && filteredModelList.size() == 0) { 
        Toast.makeText(MainActivity.this, "Not Found", Toast.LENGTH_SHORT).show(); 
        // re-load the list so the Adapter refreshes the RecyclerView list View. 
        adapter.clear(); 
        adapter.addAll(allList); 
       } else if (!mSearchView.isIconified() && filteredModelList.size() > 0) {        
        adapter.setFilter(filteredModelList, s.toString()); 
        mRecyclerView.scrollToPosition(0); 
       } 
      } 
     } 
    }); 

private ArrayList<ListItem> filter(List<ListItem> models, String query) { 

    query = query.toLowerCase(); 

    final ArrayList<ListItem> filteredModelList = new ArrayList<>(); 
    for (ListItem listItem : models) { 
     final String text = listItem.getTodo().toLowerCase(); 
     final String text2 = listItem.getNote1().toLowerCase(); 
     final String text3 = listItem.getNote2().toLowerCase(); 
     if (text.contains(query) || text2.contains(query) || 
      text3.contains(query)) { 
      filteredModelList.add(listItem); 
     } 
    } 
    return filteredModelList; 
} 

RecyclerItemClickListener: 

public interface RecyclerItemClickListener { 

    void onItemClick(View view, int position); 
} 

CardViewDetails: 

public class CardViewDetails extends AppCompatActivity { 

private int position; 
private SQLiteDB helper; 
List<ListItem> listItems; 
private CardView cardview; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_details); 

    final CardView cardView = (CardView) findViewById(R.id.dets); 

    // Create a variable for the skychill footer text. 
    final TextView skychilltext5; 

    // A db helper instance is needed for the removeItem() below 
    // when the user Longclicks the skycard for deletion. 
    helper = new SQLiteDB(this); 

    // Get the position of the clicked on R. list CardView from 
    // the MainActivity's intent bundle. 
    Bundle extras = getIntent().getExtras(); 
    if (extras != null) { 
     // get the CardView item using the int position from the 
     // MainActivity's onItemClick() and the putExtra in the intent. 
     position = extras.getInt("position",0); // 0 is default value 
    } 

    cb2 = (TextView) findViewById(R.id.cb2); 

    helper = new SQLiteDB(this); 
    listItems = new ArrayList<>(); 
    listItems = helper.getAllDBItems(); 

    cb2.setText(listItems.get(position).getTodo()); 

    ... 

} 
+0

當將單擊事件傳遞給MainActivity時,MainActivity可能仍然使用「舊」未過濾列表而不是已過濾列表來確定要對其執行操作的項目? – FWeigl

+0

@Ascorbin可能是這樣。我被困在如何解決。有任何想法嗎? – AJW

+0

可能有,如果您發佈了您的相關部分MainActivity;) – FWeigl

回答

1

施加濾波器的sql DB後(getAllDBItems)數據保持相同。您僅通過positionCardViewDetail。和SQL數據是原始列表。

你應該通過你的列表項爲parcelableCardViewDetails而不是位置。你的問題將得到解決。

+0

非常好,我究竟是如何實現的。最後一部分我正在努力的是如何在用戶編輯數據時更新CardViewDetails上的視圖。我在這裏問了一個新問題:https://stackoverflow.com/questions/46046633/recyclerview-how-to-refresh-details-activity我將不勝感激關於如何解決任何想法或想法。 – AJW

相關問題