2012-02-24 49 views
5

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

public class editview extends ListActivity { 
    private dbadapter mydbhelper; 
    private PopupWindow pw; 
    public static int editCount; 
    public static ListView listView; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mydbhelper = new dbadapter(this); 
     mydbhelper.open(); 


     View footer = getLayoutInflater().inflate(R.layout.footer_layout, null); 
     ListView listView = getListView(); 
     listView.addFooterView(footer); 
     showResults(); 
     } 

    //Populate view 
    private void showResults(){ 
     Cursor cursor = mydbhelper.getUserWord(); 
     startManagingCursor(cursor); 
     String[] from = new String[] {dbadapter.KEY_USERWORD}; 
     int[] to = new int[] {R.id.textType}; 
     ItemAdapter adapter = new ItemAdapter(this, R.layout.edit_row, cursor, 
         from, to); 
      adapter.notifyDataSetChanged(); 
      this.setListAdapter(adapter); 
      editCount = adapter.getCount(); 

    } 


      //footer button 
      public void onClick(View footer){ 
        final MediaPlayer editClickSound = MediaPlayer.create(this, R.raw.button50); 
        editClickSound.start(); 
        startActivity(new Intent("wanted.pro.madlibs.OUTPUT")); 

       } 

//custom cursor adapter 
class ItemAdapter extends SimpleCursorAdapter { 
    private LayoutInflater mInflater; 
    private Cursor cursor; 


    public ItemAdapter(Context context, int layout, Cursor cursor, String[] from, 
      int[] to) { 
     super(context, layout, cursor, from, to); 
     this.cursor = cursor; 
     mInflater = LayoutInflater.from(context); 

    } 


    static class ViewHolder { 
     protected TextView text; 
     protected EditText edittext; 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 


     ViewHolder holder; 
     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.edit_row, null); 


      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.textType); 
      holder.edittext = (EditText) convertView.findViewById(R.id.editText); 



      convertView.setTag(holder); 

     } else { 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     cursor.moveToPosition(position); 
     int label_index = cursor.getColumnIndex("userword"); 
     String label = cursor.getString(label_index); 

     holder.text.setText(label); 

     return convertView; 

    } 

} 

class ItemAdapter extends SimpleCursorAdapter { 
    private LayoutInflater mInflater; 
    private Cursor cursor; 
    Map<Integer, String> inputValues = new HashMap<Integer, String>(); 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     .... 

     ViewHolder holder; 
     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.edit_row, null); 


      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.textType); 
      holder.edittext = (EditText) convertView.findViewById(R.id.editText); 


      convertView.setTag(holder); 

     } else { 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     cursor.moveToPosition(position); 
     int label_index = cursor.getColumnIndex("userword"); 
     String label = cursor.getString(label_index); 

     holder.text.setText(label); 
     String oldText = inputValues.get(position); 
     holder.edittext.setText(oldText == null ? "" : oldText); 
     holder.edittext.addTextChangedListener(new TextWatcher(){ 
      public void afterTextChanged(Editable editable) { 
       inputValues.put(position, editable.toString()); 
      } 

करने के लिए इसे बदल दिया है, लेकिन यह करने के बाद सभी edittext रीसाइक्लिंग है डेटा है। Holder.edittext.setText (oldText) का उपयोग करने का प्रयास किया लेकिन एक ही प्रभाव।

Start filling in fields

Finish filling in fields

Scroll up.

उत्तर

4

पहले सभी की, क्या तुम सच में अपने विचार रीसाइक्लिंग से सूची दृश्य को रोकने के लिए नहीं करना चाहती। रीसाइक्लिंग देखें एक बड़ा अनुकूलन है। सूचियों पर बहुत सारी अच्छी जानकारी के लिए, Google आईओ टॉक देखें: http://www.youtube.com/watch?v=wDBM6wVEO70

कहा जा रहा है कि आपने अपनी समस्या को सही ढंग से पहचाना है: आपकी सूची में आइटमों की तुलना में आपके पास बहुत कम संपादन टेक्स्ट हैं। जैसा कि आप सूची के माध्यम से स्क्रॉल करते हैं, उन संपादन टेक्स्ट को पुनर्नवीनीकरण किया जाता है ताकि आप एक ही इनपुट को बार-बार देख सकें।

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

@Override 
public View getView(final int position, View convertView, ViewGroup parent){ 
    ... 
    cursor.moveToPosition(position); 
    int label_index = cursor.getColumnIndex("userword"); 
    String label = cursor.getString(label_index); 

    holder.text.setText(label); 

    //clear whatever text was there from some other position 
    //and set it to whatever text the user edited for the current 
    //position if available 
    String oldText = yourMapOfPositionsToValues.get(position); 
    holder.setText(oldText == null ? "" : oldText); 

    //every time the user adds/removes a character from the edit text, save 
    //the current value of the edit text to retrieve later 
    holder.edittext.addTextChangedListener(new TextWatcher(){ 
     @Override 
     public void afterTextChanged(Editable editable) { 
      yourMapOfPositionsToValues.put(position, editable.toString()); 
     } 
     .... 
    }; 

    return convertView; 
} 

जब भी अपने प्रयोक्ता को सम्पादित किया जाता है, तो आप अपने आंकड़ा संरचना के माध्यम से चलाने के लिए और क्या कर सकते हैं उन मूल्यों के साथ जो कुछ भी।

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

मैं क्योंकि मुझे लगता है कि इससे पहले कि का उपयोग किया है afterTextChanged को onTextChanged बदल गया है और मैं यह काम करता है पता है। ध्यान रखें कि बाद में टेक्स्ट परिवर्तन को हर बार एक बेहतर परिवर्तन कहा जाता है, न कि उपयोगकर्ता शब्द लिखने के ठीक बाद। यदि उपयोगकर्ता "कुत्ते" के बाद टाइप करता है तो टेक्स्ट चेंज को तीन बार कहा जाएगा, पहले 'डी' के साथ, फिर 'डू' के साथ, फिर 'कुत्ते' के साथ।

ए हैश मैप सरल है: अपनाMapOfPositionsToValues ​​= नया हैश मैप();

किसी आइटम को जोड़ने या अपडेट करने के लिए: yourMap.put (स्थिति, कुछ टेक्स्ट); किसी आइटम को लाने के लिए: yourMap.get (स्थिति);

यदि हैशैप्स समझ में नहीं आता है, तो उन्हें शोध करने में कुछ समय व्यतीत करें। वे एक अविश्वसनीय रूप से महत्वपूर्ण डेटा संरचना हैं।

आपका टेक्स्टवॉचर कार्यान्वयन गलत है। आपकी डेटा संरचना एक दृश्य से संबंधित नहीं होनी चाहिए, बल्कि गतिविधि या आपके एडाप्टर से संबंधित होनी चाहिए। ऐसा लगता है कि पद स्थिर नहीं हैं क्योंकि आपकी सूची प्रत्येक दृश्य के स्वामित्व में है। स्थिति तब तक स्थिर होती है जब तक अंतर्निहित डेटा बदलता नहीं है कर्सर एक ही स्थिति के लिए हर बार एक ही डेटा वापस कर देगा। हालांकि, संपादन टेक्स्ट का उपयोग कई अलग-अलग स्थितियों के लिए किया जाता है।

एक हैशैप को एक उदाहरण चर के रूप में बनाएं जो मैंने आपके एडाप्टर के निर्माता में ऊपर दिखाया है। फिर मूल रूप से लिखा गया टेक्स्टवॉचर जोड़ें, नामित वर्ग की कोई आवश्यकता नहीं है, अज्ञात सरल है। आपका कोड काम करना चाहिए।

+0

मैं बाद के प्रदर्शन के साथ खेल रहा था लेकिन मुझे पता चला कि यह मूल्यों को संग्रहीत नहीं कर रहा था कि मैं इसे कैसे चाहता था। आईई यह स्ट्रिंग के केवल हिस्से को ऐरे के विभिन्न हिस्सों में स्टोर करेगा। मैं अंतिम संपादन में कुत्ते की तरह कुछ टाइप कर सकता हूं और जब मैं ArrayList संपादन टेक्स्टक्स्ट में पदों को कॉल करता हूं। यह pos1 कुत्ते pos2 do pos3 करते हैं। मुझे समझ में नहीं आया कि यह केवल edittext स्ट्रिंग का हिस्सा क्यों पकड़ रहा था। – maebe

+0

पदों के लिए अविश्वसनीय लग रहा था, लेकिन शायद मैं उन्हें गलत कह रहा था। जब मैं एक सरल कर्सर एडाप्टर का उपयोग कर रहा था तो मैंने लूप के माध्यम से एडिटेक्स्ट की आईडी बदल दी और उस लूप को स्टोर करने और अगली गतिविधि पर कॉल करने के लिए उपयोग किया। लेकिन अभी भी रीसाइक्लिंग समस्याओं में भाग गया। मैंने पिछले दो हफ्तों के लिए हैशैप्स को बंद कर दिया है लेकिन उन्हें उपयोग करने के तरीके को समझाते हुए कोई अच्छी जानकारी नहीं मिल रही है। यहाँ और वहां कोड के केवल बिट्स। – maebe

+0

// TextWatcher, बाद में उपयोग के लिए डेटा को ऐरे में सहेजता है। कक्षा निरीक्षक TextWatcher लागू करता है { निजी int स्थिति; सार्वजनिक निरीक्षक (int स्थिति) { यह.position = स्थिति; } \t सार्वजनिक शून्य afterTextChanged (संपादन योग्य रों) { \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t Log.e (String.valueOf (स्थिति), "स्थिति पूर्णांक है") ; \t स्ट्रिंग टेक्स्ट = s.toString(); \t editview.editTextList.add (स्थिति, टेक्स्ट); क्या मैं अपने टेक्स्टवॉचर – maebe

1

इसका समाधान टेक्स्ट सेट करने से पहले जोड़े गए टेक्स्टवॉचर को हटा रहा है। अन्यथा, उस दृश्य पर पिछले टेक्स्टवॉचर को अभी भी नए टेक्स्टवॉचर के साथ बुलाया जाएगा। इसका ट्रैक रखने के लिए टेक्स्टटेचर को एडिटटेक्स्ट पर एक टैग के रूप में स्टोर करें।

Object oldWatcher = viewHolder.quantitySold.getTag(); 
    if(oldWatcher != null){ 
     viewHolder.quantitySold.removeTextChangedListener((CustomTextWatcher)oldWatcher); 
    } 
    String oldText = inputValues.get("key"+position); 
    Log.d(TAG, "oldText: "+oldText+" position: "+position); 
    viewHolder.quantitySold.setText(oldText == null ? "" : oldText); 
    CustomTextWatcher watcher = new CustomTextWatcher(
      cursor.getString(SKUFragment.COL_NAME), 
      cursor.getInt(SKUFragment.COL_ID), 
      cursor.getDouble(SKUFragment.COL_UNIT_PRICE), 
      position 
    ) { 
     @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) { 
      if (s != null) { 
       int quantity = 0; 
       if (!TextUtils.isEmpty(s.toString())) { 
        quantity = Integer.parseInt(s.toString()); 
        inputValues.put("key"+mPosition, "" + quantity); 
       }else{ 
        inputValues.put("key"+mPosition, ""); 
       } 
       double value = quantity * skuPrice; 
       mListener.onQuantityChanged(skuName+", position: "+mPosition, skuId, quantity, value); 
      } 
     } 
    }; 
    viewHolder.quantitySold.setTag(watcher); 
    viewHolder.quantitySold.addTextChangedListener(watcher);