2017-09-03 11 views
0

私はCardViewアイテムのRecyclerViewリストを持っています。次に、SearchViewウィジェットで簡単なフィルタメソッドを使用してリストをフィルタリングします。フィルタリングされたCardViewをクリックしてCardViewDetailsアクティビティを起動すると、UIは元のリストからCardViewを表示し、フィルタリングされたリストは表示しません。たとえば、元のリストに20項目のリストがあります。検索制約を入力すると、フィルタリングされたリストはRecyclerViewに3つのCardViewを正しく表示します。リストの3番目のCardViewをクリックすると、UIは3番目のCardViewを元のリストから返し、3番目の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を)データが同じままです。 positionのみをに渡しています。CardViewDetail。そして、SQLデータはオリジナルのリストです。

あなたはparcelableCardViewDetailsに代わりの位置としてあなたのListItemを渡す必要があります。あなたの問題は解決されます。

+0

非常に良好で、正確にどのように達成しましたか。私が苦労している最後の部分は、ユーザーがデータを編集したときにCardViewDetailsのビューを更新する方法です。私はここで新しい質問をしました:https://stackoverflow.com/questions/46046633/recyclerview-how-to-refresh-details-activity解決方法に関する考えやアイデアを感謝します。 – AJW

関連する問題