2017-09-03 4 views
0

CardView 항목의 RecyclerView 목록이 있습니다. 그런 다음 SearchView 위젯과 함께 간단한 필터 메소드를 사용하여 목록을 필터링합니다. 그런 다음 필터링 된 CardView를 클릭하여 CardViewDetails 활동을 시작하면 UI는 필터링 된 목록이 아니라 원래 목록에서 CardView를 보여줍니다. 예를 들어 원본 목록에 20 개의 항목 목록이 있습니다. 검색 제약 조건을 입력하면 필터링 된 목록에 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

Click 이벤트를 MainActivity로 전달할 때 MainActivity는 필터링 된 목록 대신 필터링되지 않은 "이전"목록을 사용하여 작업 할 항목을 결정할 수 있습니다. – FWeigl

+0

@Ascorbin 아마 케이스. 나는 고치는 방법에 붙어있다. 어떤 아이디어? – AJW

+0

MainActivity의 관련 부분을 게시하는 경우) – FWeigl

답변

1

필터는 SQL DB 적용한 후 (getAllDBItems를) 데이터가 동일하게 유지. position에 전달하는 중입니다. CardViewDetail. 그리고 SQL 데이터는 원래 목록입니다.

당신은 parcelable 대신 위치의 CardViewDetails에 대한 사용자의 을 ListItem을 통과해야한다. 당신의 문제는 해결 될 것입니다.

+0

매우 훌륭하고 정확하게 달성했습니다. 내가 고민하고있는 마지막 부분은 사용자가 데이터를 편집 할 때 CardViewDetails의 뷰를 업데이트하는 방법입니다. 저는 여기에 새로운 질문을했습니다 : https://stackoverflow.com/questions/46046633/recyclerview-how-to-refresh-details-activity 해결 방법에 대한 생각이나 아이디어에 감사드립니다. – AJW

관련 문제