2017-09-03 35 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