2013-08-19 6 views
9

मैं अपने स्वयं के ऑब्जेक्ट्स (केवल एक प्रकार) की सूची के लिए एक ऐरेएडाप्टर का उपयोग कर रहा हूं और मैं उपयोगकर्ता को अधिक आइटम बनाने का विकल्प देता हूं (इस प्रकार उन वस्तुओं के लिए और अधिक विचार)। किसी बिंदु पर, GetView ने एक गैर-शून्य "कन्वर्ट व्यू" के साथ एक नई "स्थिति" अनुक्रमणिका भेजी। यह तब अंतिम स्थिति में पहला दृश्य दिखाता है। उसके बाद, विचारों को स्क्रॉल करते समय सभी मिश्रित हो जाते हैं। मुझे लगता है कि इसका मतलब यह है कि मैंने विचारों को उन तरीकों से छेड़छाड़ की है जिनके पास मुझे नहीं होना चाहिए, लेकिन मुझे बस यह नहीं दिख रहा है। यहां कुछ कोड दिया गया है:गेटव्यू पैरामीटर "कन्वर्टव्यू" नया "स्थिति" पैरामीटर पर शून्य नहीं है

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v; 
    PreviewItemHolder holder = null; 

    // Initialize view if convertview is null 
    if (convertView == null) { 
     v = newView(parent, position); 
    } 
    // Populate from previously saved holder 
    else { 
     // Use previous item if not null 
     v = convertView; 
    } 

    // Populate if the holder is null (newly inflated view) OR 
    // if current view's holder's flag is true and requires populating 
    if ((holder == null) || (holder.readPopulateFlag())) { 
     bindView(position, v); 
    } 

    return v; 
} 

    private View newView(ViewGroup parent, int position) { 
    // Getting view somehow... 
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View inflatedView = inflater.inflate(R.layout.preview_element_set, parent, false); 
    PreviewItemHolder holder = new PreviewItemHolder(); 

    holder.set = (Set) mSets.get(position); 
    holder.previewElementHolders = new ArrayList<PreviewElementHolder>(); 
    holder.expandArea = (View) inflatedView.findViewById(R.id.expandArea); 
    holder.repetitionsLabel = (TextView) inflatedView.findViewById(R.id.previewRepetitionsInput); 
    holder.endlessInput = (CheckBox) inflatedView.findViewById(R.id.previewSetEndlessInput); 
    holder.nameLabel = (TextView) inflatedView.findViewById(R.id.previewSetNameLabel); 
    holder.commentInput = (EditText) inflatedView.findViewById(R.id.previewSetCommentInput); 
    holder.soundInput = (EditText) inflatedView.findViewById(R.id.previewSetSoundInput); 
    holder.addElementButton = (Button) inflatedView.findViewById(R.id.previewSetAddElements); 
    holder.expand = (View) inflatedView.findViewById(R.id.infoArea); 
    holder.collapse = (View) inflatedView.findViewById(R.id.collapse); 

    final int setsLength = holder.set.getElements().size(); 

    for (int i = 0; i < setsLength; i++) { 
     AElement currElement = holder.set.getElements().get(i); 

     // Creating new element holder according to the type 
     if (currElement instanceof Rest) { 
      holder.previewElementHolders.add(new PreviewRestHolder()); 
     } 
     else if (currElement instanceof TimeExercise) { 
      holder.previewElementHolders.add(new PreviewTimeExerciseHolder()); 
     } 
     else if (currElement instanceof RepetitionExercise) { 
      holder.previewElementHolders.add(new PreviewRepetitionExerciseHolder()); 
     } 

     View currLayout = inflateElement(currElement, inflater, i, holder.previewElementHolders.get(i)); 

     // Add the child before the hairline, collapse image and the add 
     // button 
     // (3 last children of the expandArea view 
     ((ViewGroup) holder.expandArea).addView(currLayout, ((ViewGroup) holder.expandArea).getChildCount() - CHILDREN_INDEX_AFTER_PHASES_LABEL); 
    } 

    inflatedView.setTag(holder); 

    return inflatedView; 
} 

private void bindView(int position, View inflatedView) { 
    final PreviewItemHolder holder = (PreviewItemHolder) inflatedView.getTag(); 
    holder.set.setId(position); 
    holder.endlessInput.setChecked(holder.set.getEndless()); 
    holder.soundInput.setText(holder.set.getSound()); 
    holder.nameLabel.setText(holder.set.getName()); 
    holder.commentInput.setText(holder.set.getComment()); 

    // Make sure there is a name. If none, put default 
    if (holder.nameLabel.getText().equals("")) { 
     holder.nameLabel.setText(R.string.default_set_name); 
    } 

    // Set repetitions value according to the endless flag 
    if (holder.set.getEndless()) { 
     holder.repetitionsLabel.setText(R.string.infinity); 
    } 
    else { 
     holder.repetitionsLabel.setText(String.valueOf(holder.set.getRepetitions())); 
    } 

    // Set click listeners 
    holder.endlessInput.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

      // Save endless flag 
      holder.set.setEndless(isChecked); 

      // If an endless set - Dropset 
      if (isChecked) { 
       holder.repetitionsLabel.setText(R.string.infinity); 
      } 
      else { 
       // Regular set 
       holder.repetitionsLabel.setText(String.valueOf(holder.set.getRepetitions())); 
      } 

      hideShowRepsWeights(holder); 
     } 

    }); 

    holder.repetitionsLabel.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      NumericDialog instance = NumericDialog.newInstance(holder, holder.set, NumericDialog.INTEGER_MODE, Consts.SET_REPETITIONS_METHOD_NAME); 
      instance.show(((Activity) getContext()).getFragmentManager(), null); 
     } 
    }); 

    holder.nameLabel.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // Setting flag to true to allow populating this view 
      holder.rePopulateFlag = true; 
      SetNameDialog instance = SetNameDialog.newInstance(holder.set); 
      instance.show(((Activity) getContext()).getFragmentManager(), null); 
     } 
    }); 

    holder.commentInput.setOnFocusChangeListener(new OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (!hasFocus) { 
       // After focus is lost, save the text into the set 
       holder.set.setComment(holder.commentInput.getText().toString()); 
      } 
     } 
    }); 

    // TODO Change that into a dialog that allows selection of sounds 
    holder.soundInput.setOnFocusChangeListener(new OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (!hasFocus) { 
       // After focus is lost, save the text into the set 
       holder.set.setSound(holder.soundInput.getText().toString()); 
      } 
     } 
    }); 

    holder.expand.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // Change visibility - Show expandArea and its data 
      holder.expandArea.setVisibility(View.VISIBLE); 
      holder.expand.setVisibility(View.GONE); 
      holder.collapse.setVisibility(View.VISIBLE); 
     } 
    }); 

    holder.collapse.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // Change visibility - Hide expandArea and its data 
      holder.expandArea.setVisibility(View.GONE); 
      holder.collapse.setVisibility(View.GONE); 
      holder.expand.setVisibility(View.VISIBLE); 
     } 
    }); 

    holder.addElementButton.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      AddElementDialog instance = AddElementDialog.newInstance(holder); 
      instance.show(((Activity) getContext()).getFragmentManager(), null); 
     } 
    }); 

    // Populate elements 
    for (PreviewElementHolder elementHolder : holder.previewElementHolders) { 
     populateElement(elementHolder, holder); 
    } 

    // Finally hide/show if needed - Should this be put somewere else? 
    hideShowRepsWeights(holder); 
} 

कृपया मुझे बताएं कि क्या आपको लगता है कि मुझे चीजों को स्पष्ट करने के लिए और अधिक विधियां अपलोड करनी चाहिए।

+0

धारक क्या है .readPopulateFlag() ?? –

उत्तर

15

एक दोस्त ने मुझे समस्या की व्याख्या की और अब यह काम करता प्रतीत होता है। असल में ListView में केवल कुछ ही विचार हैं और उन्हें हर समय रीसायकल करते हैं। मेरे मामले में मेरे पास नेक्सस 4 है और इसलिए ऐसा लगता है कि 8 विचार कुल हैं क्योंकि 8 वें हमेशा परेशानी का कारण बनने वाले थे। मेरे getView() में जो लापता था, वह एरिया एडाप्टर के भीतर वर्तमान आइटम की स्थिति और आईडी के बीच सहसंबंध की जांच की स्थिति थी। यहाँ कैसे यह अब कि यह काम करता दिखाई देता है:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v; 
    PreviewItemHolder holder = null; 

    // Initialize view if convertview is null 
    if (convertView == null) { 
     v = newView(parent, position); 
    } 
    // Populate from previously saved holder 
    else { 
     // If position and id of set do not match, this view needs to be re-created, not recycled 
     if (((PreviewItemHolder) convertView.getTag()).set.getId() != position) { 
      v = newView(parent, position); 
     } 
     else { 
      // Use previous item if not null 
      v = convertView; 

      // Get holder 
      holder = (PreviewItemHolder) v.getTag(); 
     } 
    } 

    // Populate if the holder is null (newly inflated view) OR 
    // if current view's holder's flag is true and requires populating 
    if ((holder == null) || (holder.readPopulateFlag())) { 
    bindView(position, v); 
    } 

    return v; 
} 
+0

मेरे पास बेसएडाप्टर के साथ एक ही समस्या थी, लेकिन मेरा दिमाग यह नहीं ले सकता ... मुझे पता है कि यह बहुत समय पहले था, लेकिन क्या आपके पास कुछ और स्पष्टीकरण है कि इससे मदद क्यों मिली? यह मेरी मदद भी करता है, मैं समझ में नहीं आता ... – keybee

+0

यह उत्कृष्ट है। जब मैं अपने 'ListView' में 3 अलग-अलग प्रकार के लेआउट का उपयोग कर रहा था तब भी वही समस्या मेरे साथ हुई। जैसे ही शीर्ष दृश्य दृश्य 1 का होता है और स्क्रीन पर प्रवेश करने के लिए अगला दृश्य किसी अन्य प्रकार का होता है, 'कन्वर्ट व्यू' शून्य नहीं था और 'getTag' का उपयोग करके गलत दृश्य पुनर्नवीनीकरण किया गया था। –

1

आपको bindView()हमेशा पर कॉल करने की आवश्यकता है। विचार या पुन: उपयोग निम्नानुसार है। यदि convertView शून्य है, तो आप एक नया दृश्य बनाते और प्रारंभ करते हैं। यदि convertView शून्य नहीं है, तो आप इस दृश्य को लेते हैं और को नए दृश्य के रूप में परिवर्तित करते हैं, जिसका अर्थ है कि आप को convertView उदाहरण के साथ कॉल करते हैं। अधिक जानकारी के लिए

चेकआउट this Javadoc

+0

मैंने कोशिश की लेकिन इसने समस्या को हल नहीं किया। यहां तक ​​कि जब भी मैं bindView() को हर बार कॉल करता हूं, तब भी समस्या तब भी होती है जैसा उसने पहले किया था। मुझे नहीं लगता कि आपको इसे ठीक करने के लिए हर बार कनवर्टर में डेटा को फिर से सेट करना होगा। –

0

जब आप कि पुनर्नवीनीकरण किया जाना चाहिए आप सूची दृश्य कितने प्रकार आप विधि को लागू द्वारा मिल गया है यह बताने के लिए है विचारों के कई प्रकार है

@Override 
    public int getViewTypeCount() { 
     return 7; 
    } 
संबंधित मुद्दे