2016-10-07 1 views
1

Edit:chaîne Spannable travailler uniquement pour le dernier article dans ListView

Je suis maintenant en mesure de frapper des mots dans le listview mais seulement en mesure de le faire à partir du bas vers le haut et ne peut unstrike l'élément de fond après. Le code est ci-dessous. J'essaye d'avoir le coup traversant un TextView si son critère est rencontré. Logiquement cela fonctionne, mais seulement pour le dernier élément dans ListView. Tous les autres objets ne semblent pas créer la grève du tout. Mon code est ci-dessous:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    subTask = getItem(position); 

    if(convertView == null){ 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.subtask_adapter_list, parent, false); 
    } 

    tasksTitle = (TextView)convertView.findViewById(R.id.tasksName); 
    tasksTitle.setTypeface(typeface); 
    completed = (CheckBox)convertView.findViewById(R.id.completed); 
    changeColor(); 

    tasksTitle.setText(subTask.getSubTask()); 

    toggleLineThrough(subTask.getSubTask()); 

    completed.setChecked(subTask.isCompleted()); 

    completed.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if(completed.isChecked()){ 
       subTask.setCompleted(true); 
       subTask.save(); 
       toggleLineThrough(subTask.getSubTask()); 
      } else { 
       subTask.setCompleted(false); 
       subTask.save(); 
       toggleLineThrough(subTask.getSubTask()); 
      } 
     } 
    }); 

    return convertView; 
} 

private void toggleLineThrough(String text){ 
    SpannableString styledString = new SpannableString(text); 
    if(completed.isChecked()){ 
     styledString.setSpan(new StrikethroughSpan(), 0, text.length(), 0); 
     tasksTitle.setText(styledString); 
    } else { 
     tasksTitle.setText(text); 
    } 
} 

Je ne peux pas sembler obtenir le coup de travailler pour tous. J'ai aussi essayé d'utiliser la méthode Paint Flags avec le même résultat (même en masquant complètement mon TextView). Toute aide utilisant Spannable String pour mes TextViews dans ListView serait vraiment appréciée.

Répondre

0

Vous devez également passer l'état vérifié et tasksTitle à toggleLineThrough() également. Les variables completed et tasksTitle contiennent des valeurs incorrectes car onClickListener est appelé plus tard que getView(). Ils ont été remplacés plusieurs fois par des appels consécutifs de getView().

+0

Ah merci !! Je vais y aller maintenant. Merci Sergey. – SmiffyKmc

+0

J'ai donc essayé de faire passer ces deux-là dans la fonction et semble être à mi-chemin à moins que je ne me trompe. Je suis seulement en mesure de faire tous les éléments ont leur texte frappé si je commence par le bas vers le haut. Mais je peux seulement indiquer le fond alors après cela? Je vais modifier le code ci-dessus. – SmiffyKmc

0

@SmiffyKmc, J'essaie d'utiliser ce qui suit pour répondre à d'autres questions similaires, donc certains commentaires peuvent ne pas être liés à votre problème.

ont fait un échantillon complété ici:

dans strings.xml:

<string-array name="list_items_sample"> 
    <item>One</item> 
    <item>Two</item> 
    <item>Three</item> 
    <item>Four</item> 
    <item>Five</item> 
    <item>Six</item> 
    <item>Seven</item> 
    <item>Eight</item> 
    <item>Nine</item> 
    <item>Ten</item> 
    <item>Eleven</item> 
    <item>Twelve</item> 
    <item>Thirteen</item> 
    <item>Fourteen</item> 
    <item>Fifteen</item> 
    <item>Sixteen</item> 
    <item>Seventeen</item> 
    <item>Eighteen</item> 
    <item>Nineteen</item> 
    <item>Twenty</item> 
</string-array> 

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="${relativePackage}.${activityClass}" > 

<ListView 
    android:id="@+id/listView1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="7dp" > 

</ListView> 

custom_list_items.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/RelativeLayout1" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:orientation="horizontal" 
android:paddingBottom="20dp" 
android:paddingTop="20dp" > 

<CheckBox 
    android:id="@+id/cb" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentEnd="true" 
    android:layout_alignParentRight="true" 
    android:focusable="false" /> 

<TextView 
    android:id="@+id/tvId" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignBaseline="@+id/cb" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:layout_alignParentTop="true" 
    android:layout_marginBottom="5dp" 
    android:layout_marginTop="5dp" 
    android:gravity="center" 
    android:minWidth="70dp" 
    android:textSize="25sp" /> 

<TextView 
    android:id="@+id/tvDescription" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignBaseline="@+id/cb" 
    android:layout_alignParentTop="true" 
    android:layout_toEndOf="@id/tvId" 
    android:layout_toLeftOf="@+id/cb" 
    android:layout_toRightOf="@id/tvId" 
    android:layout_toStartOf="@id/cb" /> 

MainActivity.java:

public class MainActivity extends Activity { 
static final String ITEM_ID = "item_id"; 
static final String ITEM_NAME = "item_name"; 
static final String ITEM_CHECKED ="item_checked"; 
ListView mListView; 

ArrayList<HashMap<String, Object>> mDataList = new ArrayList<>(); 
ArrayAdapter<HashMap<String, Object>> mArrayAdapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mListView = (ListView) findViewById(R.id.listView1); 

    String items[] = getResources().getStringArray(R.array.list_items_sample); 
    mDataList.clear(); 
    for(int i=1; i<20; i++){ 
     HashMap<String, Object> newItem = new HashMap<String, Object>(); 
     newItem.put(ITEM_ID, String.valueOf(i)); 
     newItem.put(ITEM_NAME, "Sample<"+items[i-1]+">"); 
     newItem.put(ITEM_CHECKED, false); 
     mDataList.add(newItem); 
    } 

    mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 

    mArrayAdapter = new ArrayAdapter<HashMap<String, Object>>(getApplicationContext(), R.layout.custom_list_items, mDataList){ 
     class ViewHolder{ 
      CheckBox cb; 
      TextView tvId; 
      TextView tvDescription; 
     } 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      ViewHolder holder; 
      // Prepare views ready for data 
      if(convertView == null){ 
       convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_list_items, parent, false); 
       holder = new ViewHolder(); 
       holder.cb = (CheckBox) convertView.findViewById(R.id.cb); 
       holder.tvId = (TextView) convertView.findViewById(R.id.tvId); 
       holder.tvDescription = (TextView) convertView.findViewById(R.id.tvDescription); 
       convertView.setTag(holder); 

       holder.cb.setOnClickListener(new OnClickListener(){ 
        @Override 
        public void onClick(View view) { 
         // Get view, position and DataList(position) 
         CheckBox buttonView = (CheckBox) view; 
         int pos = (int) buttonView.getTag(); 
         HashMap<String, Object> selectedItem = new HashMap<String, Object>(); 
         selectedItem = getItem(pos); 

         // Update DataList 
         remove(selectedItem); 
         selectedItem.remove(ITEM_CHECKED); 
         if(buttonView.isChecked()){ 
          selectedItem.put(ITEM_CHECKED, true); 
          insert(selectedItem, pos); 
         }else{ 
          selectedItem.put(ITEM_CHECKED, false); 
          insert(selectedItem, pos); 
         } 

         // Update all UI views by 
         notifyDataSetChanged(); 
         // or Update the affected views directly 
//       View itemView = (View) buttonView.getParent(); 
//       TextView tv = (TextView) itemView.findViewById(R.id.tvDescription); 
//       toggleLineThrough(tv, (String)getItem(pos).get(ITEM_NAME), buttonView.isChecked()); 
        } 
       }); 
      }else{ 
       holder = (ViewHolder) convertView.getTag(); 
      } 

      // Get data from DataList 
      HashMap<String, Object> currentItem = getItem(position); 

      // Setup List items UI 
      holder.tvId.setText((String)currentItem.get(ITEM_ID)); 
      holder.cb.setChecked((boolean)currentItem.get(ITEM_CHECKED)); 
      toggleLineThrough(holder.tvDescription, (String)currentItem.get(ITEM_NAME), (boolean)currentItem.get(ITEM_CHECKED)); 

      // Save position to CheckBox, so position can be retrieved when CheckBox is clicked 
      holder.cb.setTag(position); 

      return convertView; 
     } 
     private void toggleLineThrough(TextView tasksTitle, String title, boolean completed){ 
      SpannableString styledString = new SpannableString(title); 
      if(completed == true){ 
       styledString.setSpan(new StrikethroughSpan(), 0, title.length(), 0); 
       tasksTitle.setText(styledString); 
      }else{ 
       tasksTitle.setText(title); 
      } 
     } 
    }; 
    mListView.setAdapter(mArrayAdapter); 
} 
} 

Quelques points importants:

  1. keep state de la CheckBox comme un champ dans la liste des données et l'interface utilisateur de configuration en conséquence, sinon ListView sera erroné après défilement. Get12() est terminé lorsque le ListView est affiché. OnClickListener NE DEVRAIT PAS utiliser les données obtenues à partir de getView().
  2. OnClickListener DEVRAIT ABANDER et BESOIN d'obtenir des données de la liste de données. La méthode la plus simple peut être: "View.setTag (position) dans getView(), View.getTag() dans OnClickListener()".
  3. Ne pas seulement modifier les vues. Modifier les données, liste de données d'abord. Puis appelez notifyDataSetChanged(). S'il n'y a qu'une petite modification à l'interface utilisateur, vous pouvez le faire directement mais cela devrait être la même chose que d'appeler notifyDataSetChanged().

Espérons que cette aide!

+0

Merci beaucoup pour l'entrée! Je n'ai pas encore eu l'occasion de m'en occuper, mais je vais essayer et revenir vers vous. Merci :) – SmiffyKmc