2012-02-22 16 views
8

का उपयोग कर फ़िल्टर के साथ एकाधिक चयन के साथ एक सूचीदृश्य कार्यान्वित करना इस समस्या पर Android: Wrong item checked when filtering listview इस समस्या पर चर्चा की गई है। समस्या को सारांशित करने के लिए, किसी कर्सर एडाप्टर और फ़िल्टर के साथ एक सूचीदृश्य का उपयोग करते समय, फ़िल्टर किए गए सूची में चुने गए आइटम फ़िल्टर को हटा दिए जाने के बाद अपना चयन खो देते हैं और इसके बजाय, फ़िल्टर की स्थिति में उस स्थिति में आइटम चयनित होते हैं।एक कर्सर एडाप्टर

उपरोक्त लिंक किए गए प्रश्न में कोड नमूना का उपयोग करके, हम चेकबॉक्स को चिह्नित करने के लिए कोड कहां रखना चाहिए। मेरा मानना ​​है कि यह CustomCursorAdapter की getView() विधि में होना चाहिए, लेकिन मुझे यकीन नहीं है। साथ ही, हम कस्टम एडाप्टर क्लास में सभी चयनित आईडी को हैशसेट को कैसे एक्सेस करते हैं, क्योंकि इसे सूची में रखने वाली मुख्य गतिविधि में प्रारंभ और संशोधित किया जाएगा।

मेरे गतिविधि ListView को लागू करने

@Override 
public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.selectfriends); 

     Log.v(TAG, "onCreate called") ; 

     selectedIds = new ArrayList<String>() ; 
     selectedLines = new ArrayList<Integer>() ; 

     mDbHelper = new FriendsDbAdapter(this); 
     mDbHelper.open() ; 

     Log.v(TAG, "database opened") ; 

     Cursor c = mDbHelper.fetchAllFriends(); 
     startManagingCursor(c); 

     Log.v(TAG, "fetchAllFriends Over") ; 


     String[] from = new String[] {mDbHelper.KEY_NAME}; 
     int[] to = new int[] { R.id.text1 }; 

     final ListView listView = getListView(); 
     Log.d(TAG, "Got listView"); 

    // Now initialize the adapter and set it to display using our row 
     adapter = 
      new FriendsSimpleCursorAdapter(this, R.layout.selectfriendsrow, c, from, to); 

     Log.d(TAG, "we have got an adapter"); 
    // Initialize the filter-text box 
    //Code adapted from https://stackoverflow.com/questions/1737009/how-to-make-a-nice-looking-listview-filter-on-android 

     filterText = (EditText) findViewById(R.id.filtertext) ; 
     filterText.addTextChangedListener(filterTextWatcher) ; 

    /* Set the FilterQueryProvider, to run queries for choices 
    * that match the specified input. 
    * Code adapted from https://stackoverflow.com/questions/2002607/android-how-to-text-filter-a-listview-based-on-a-simplecursoradapter 
    */ 

     adapter.setFilterQueryProvider(new FilterQueryProvider() { 
      public Cursor runQuery(CharSequence constraint) { 
       // Search for friends whose names begin with the specified letters. 
       Log.v(TAG, "runQuery Constraint = " + constraint) ; 
       String selection = mDbHelper.KEY_NAME + " LIKE '%"+constraint+"%'"; 

       mDbHelper.open(); 
       Cursor c = mDbHelper.fetchFriendsWithSelection(
       (constraint != null ? constraint.toString() : null)); 
       return c; 
    } 
}); 




     setListAdapter(adapter); 

     Log.d(TAG, "setListAdapter worked") ; 


     listView.setItemsCanFocus(false); 
     listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 

     // listView.setOnItemClickListener(mListener); 

     Button btn; 
     btn = (Button)findViewById(R.id.buttondone); 

     mDbHelper.close(); 

    } 


    @Override 
    protected void onListItemClick(ListView parent, View v, int position, long id) { 

     String item = (String) getListAdapter().getItem(position); 
     Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show(); 

     //gets the Bookmark ID of selected position 
     Cursor cursor = (Cursor)parent.getItemAtPosition(position); 
     String bookmarkID = cursor.getString(0); 

     Log.d(TAG, "mListener -> bookmarkID = " + bookmarkID); 

     Log.d(TAG, "mListener -> position = " + position); 

//  boolean currentlyChecked = checkedStates.get(position); 
//  checkedStates.set(position, !currentlyChecked); 


     if (!selectedIds.contains(bookmarkID)) { 

      selectedIds.add(bookmarkID); 
      selectedLines.add(position); 

     } else { 

      selectedIds.remove(bookmarkID); 
      selectedLines.remove(position); 


      } 

    } 



    private TextWatcher filterTextWatcher = new TextWatcher() { 

     public void afterTextChanged(Editable s) { 

     } 

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

     } 

     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      Log.v(TAG, "onTextChanged called. s = " + s); 
      adapter.getFilter().filter(s); 
     } 
    }; 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     filterText.removeTextChangedListener(filterTextWatcher); 
    } 

मेरा कस्टम कर्सर एडाप्टर:

public class FriendsSimpleCursorAdapter extends SimpleCursorAdapter implements Filterable { 

private static final String TAG = "FriendsSimpleCursorAdapter"; 
private final Context context ; 
private final String[] values ; 
private final int layout ; 
private final Cursor cursor ; 

static class ViewHolder { 
    public CheckedTextView checkedText ; 
} 

public FriendsSimpleCursorAdapter(Context context, int layout, Cursor c, 
     String[] from, int[] to) { 
    super(context, layout, c, from, to); 
    this.context = context ; 
    this.values = from ; 
    this.layout = layout ; 
    this.cursor = c ; 
    Log.d(TAG, "At the end of the constructor") ; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    Log.d(TAG, "At the start of rowView. position = " + position) ; 
    View rowView = convertView ; 
    if(rowView == null) { 
     Log.d(TAG, "rowView = null"); 
     try { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     rowView = inflater.inflate(layout, parent, false); 
     Log.d(TAG, "rowView inflated. rowView = " + rowView); 
     ViewHolder viewHolder = new ViewHolder() ; 
     viewHolder.checkedText = (CheckedTextView) rowView.findViewById(R.id.text1) ; 
     rowView.setTag(viewHolder); 
     } 
     catch (Exception e) { 
      Log.e(TAG, "exception = " + e); 
     } 
    } 

    ViewHolder holder = (ViewHolder) rowView.getTag(); 

    int nameCol = cursor.getColumnIndex(FriendsDbAdapter.KEY_NAME) ; 
    String name = cursor.getString(nameCol); 
    holder.checkedText.setText(name); 

    Log.d(TAG, "At the end of rowView"); 
    return rowView; 

} 

}

+0

इस लिंक के अनुसार, http://codereview.stackexchange.com/questions/1057/android-custom-cursoradapter- डिज़ाइन हम नए व्यू और बाइंडव्यू ओवरराइडिंग से बेहतर हैं। – rohitmishra

उत्तर

1

मुझे लगता है कि इसे हल क्या किया:

CUR = कर्सर। सी = सरल कर्सर एडाप्टर आंतरिक कर्सर।

(members) 
static ArrayList<Boolean> checkedStates = new ArrayList<Boolean>(); 
static HashSet<String> selectedIds = new HashSet<String>(); 
static HashSet<Integer> selectedLines = new HashSet<Integer>(); 

ListView onItemClickListener में :

मेरी MainActivity में

if (!selectedIds.contains(bookmarkID)) { 

    selectedIds.add(bookmarkID); 
    selectedLines.add(position); 


} else { 

    selectedIds.remove(bookmarkID); 
    selectedLines.remove(position); 



if (selectedIds.isEmpty()) { 
    //clear everything 
     selectedIds.clear(); 
     checkedStates.clear();  
     selectedLines.clear(); 

     //refill checkedStates to avoid force close bug - out of bounds 
     if (cur.moveToFirst()) { 
      while (!cur.isAfterLast()) {  
       MainActivity.checkedStates.add(false); 

       cur.moveToNext(); 
      } 
     }      

} 

SimpleCursorAdapter में मैं जोड़ा (getView में दोनों):

// fill the checkedStates array with amount of bookmarks (prevent OutOfBounds Force close) 
     if (c.moveToFirst()) { 
      while (!c.isAfterLast()) { 
       MainActivity.checkedStates.add(false); 
       c.moveToNext(); 
      } 
     } 

और:

String bookmarkID = c.getString(0); 
     CheckedTextView markedItem = (CheckedTextView) row.findViewById(R.id.btitle); 
     if (MainActivity.selectedIds.contains(new String(bookmarkID))) { 
      markedItem.setChecked(true); 
      MainActivity.selectedLines.add(pos); 

     } else { 
      markedItem.setChecked(false); 
      MainActivity.selectedLines.remove(pos); 
     } 

आशा इस मदद करता है ... आप निश्चित रूप से अपनी आवश्यकताओं के इसे समायोजित करने की आवश्यकता होगी।

संपादित करें:

डाउनलोड अमेरिकन प्लान एसडीके, अमेरिकन प्लान लॉगिन पारित नहीं मिल सकता है। आपके पास एक बग है जहां डिवाइस पर एफबी ऐप इंस्टॉल होने पर आपको वैध access_token नहीं मिलता है। एफबी ऐप को हटा दिया और getFriends() में एफसी मिला। runOnUiThread(new Runnable...) के साथ अपने दायरे को लपेटकर इसे हल करें।

त्रुटि आप बुरा फ़िल्टरिंग के साथ कोई संबंध नहीं है मिलता है, बुरा चेकबॉक्स राज्यों ... आप इसे क्योंकि आप इसे क्वेरी करने से पहले कर्सर का उपयोग करने की कोशिश कर रहे हैं मिलता है (पहले से ही बंद कर दिया)। ऐसा लगता है कि एडाप्टर इसका उपयोग कर रहा है इससे पहले कि आप कर्सर बंद कर रहे हैं। इसे जोड़कर सत्यापित किया गया:

mDbHelper = new FriendsDbAdapter(context); 

     mDbHelper.open() ; 
     cursor = mDbHelper.fetchAllFriends(); 

SelectFriendsAdapter में getView स्कोप में सत्यापित करें।

इसे जोड़ने के बाद, यह एफसी नहीं होगा और आप अपने फ़िल्टर का ख्याल रखना शुरू कर सकते हैं। सुनिश्चित करें कि कर्सर बंद नहीं है और मूल रूप से यदि आप इसे startManagingCursor() के साथ प्रबंधित कर रहे हैं, तो इसे मैन्युअल रूप से बंद करने की आवश्यकता नहीं है।

आशा है कि आप इसे यहां से ले जा सकते हैं!

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद। मैं अभी भी setFilterQueryProvider में परेशानी का सामना कर रहा हूँ। SimpleCursorAdapter के लिए उपयोग किए जाने वाले एक ही डेटाबेस सहायक का उपयोग करके मुझे "fillWindow() त्रुटि में अमान्य वक्तव्य" मेरी सूचीत्मकता में, मैंने mDbHelper का एक उदाहरण उपयोग किया है जो मेरा डेटाबेस हैल्पर है। मैं c = mDbHelper.fetchAllFriends() के बाद एक कॉलमैनिंग कर्सर() के बाद कॉल करता हूं, मेरी सूची सक्रियता पर। क्या मुझे runQuery() में कॉल के लिए mDbHelper का एक नया उदाहरण घोषित करना चाहिए? मैं यह नहीं ढूंढ पा रहा हूं कि इससे निपटने का पसंदीदा तरीका क्या है। – rohitmishra

+0

@movingahead मुझे यकीन नहीं है कि मैं समझता हूं कि आपकी मदद कैसे करें और ओपी पोस्ट में आपके द्वारा वर्णित आपके वर्तमान प्रश्न से कैसे संबंधित है, लेकिन, आपको प्राप्त होने वाली त्रुटि के बाद, ऐसा लगता है कि एमडीबीहेल्पर को तुरंत चालू करना सही तरीका है ऑनक्रेट (नया एमडीबीहेल्पर() या जो कुछ भी) और फिर fetchFriends को कॉल करें। यहां देखें: 1. http://stackoverflow.com/questions/4195089/what-does-invalid-statement-in-fillwindow-in-android-cursor-mean 2. http://stackoverflow.com/questions/4258493/अमान्य-कथन-इन-फिलविंडो-इन-एंड्रॉइड 3. http://stackoverflow.com/questions/9049542/invalid-statement-in-fillwindow –

+0

मैंने आपके द्वारा इंगित सभी लिंक का पालन किया है। मुझे एक या एक और कर्सर त्रुटि मिल रही है। वैसे भी, मदद के लिए धन्यवाद। – rohitmishra

संबंधित मुद्दे