Aller au contenu

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

Potoman

Pb dans une ListView

Recommended Posts

Bonjour à tous !

Alors je vous explique mon petit pb...

J'utilise une ListView qui, lorsque l'utilisateur descend tout en bas en déclenchant donc la fonction getView() de la classe BaseAdapter, déclenche l'ajout d'item à la fin de cette ListView.

La listView s'agrandi donc si l'utilisateur souhaite voir d'ancien post.

Le problème c'est lors de ce déclenchement... La ListView blink et devient totalement blanc et la vue reviens tout en haut sans pour autant afficher les premier item. Il faut ensuite que l'utilisateur redescende en bas pour retrouver un contrôle plus ou moins correct de la ListView.

Sachant que les classe View et ViewGroup sont un peu obscure pour moi, je voulais savoir si quelqu'un pouvais m'aider pour se genre de problème...

Ci dessous, la code de ma classe qui hérite de BaseAdapter :

package org.example.webteam;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.potoman.tools.ObjectToDay;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class RagotAdapter extends BaseAdapter {
List<Ragot> lstRagot;
TextView textViewPseudo;
TextView textViewRagot;
TextView textViewDate;
LinearLayout ll;
LayoutInflater inflater;
int firstHistory = 0;
Ragots myRagots = null;
static int NBR_ECHELON = 8;
static int NBR_STEP = 1;
boolean ifNotAllLoad = true;
/*static int R_COLOR = 207;
static int [] V_COLOR = {101,  91,  81,  70,  60,  50,  39,  29,  19,   8,   0};
static int [] B_COLOR = {153, 148, 143, 137, 132, 127, 122, 116, 111, 106, 102};*/

static int [] R_COLOR = {204, 222, 240, 255, 205, 155, 105, 55, 5};
static int [] V_COLOR = {102, 146, 199, 255, 205, 155, 105, 55, 5};
static int [] B_COLOR = {152, 184, 219, 255, 205, 155, 105, 55, 5};

public RagotAdapter(Context context, List<Ragot> lstRagot, Ragots myRagots) {//, CheckBox essaiCheckBox) {
	inflater = LayoutInflater.from(context);
	this.lstRagot = lstRagot;
	this.firstHistory = lstRagot.get(0).getHistory();
	this.myRagots = myRagots;
}
public int getCount() {
	return lstRagot.size();
}
public Object getItem(int position) {
	return lstRagot.get(position);
}
public long getItemId(int position) {
	return position;
}

private class ViewHolder {
	LinearLayout ll;
	TextView tvRagot;
	TextView tvDate;
	TextView tvTime;
	ImageView ivCoinHautGauche;
	ImageView ivCoinHautDroite;
	ImageView ivCoinBasGauche;
	ImageView ivCoinBasDroite;
}


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

	if (ifNotAllLoad)
		if (position == lstRagot.size() - 1) {
			ifNotAllLoad = myRagots.loadOldRagot();
		}

	ViewHolder holder;
	if(convertView == null) {
		holder = new ViewHolder();
		convertView = inflater.inflate(R.layout.itemragot, null);
		holder.ll = (LinearLayout)convertView.findViewById(R.id.llCorpRagot);
		holder.tvRagot = (TextView)convertView.findViewById(R.id.tvRagot);
		holder.tvTime = (TextView)convertView.findViewById(R.id.tvTime);
		holder.tvDate = (TextView)convertView.findViewById(R.id.tvDate);
		holder.ivCoinHautGauche = (ImageView)convertView.findViewById(R.id.ivCoinHautGauche);
		holder.ivCoinHautDroite = (ImageView)convertView.findViewById(R.id.ivCoinHautDroite);
		holder.ivCoinBasGauche = (ImageView)convertView.findViewById(R.id.ivCoinBasGauche);
		holder.ivCoinBasDroite = (ImageView)convertView.findViewById(R.id.ivCoinBasDroite);
		convertView.setTag(holder);
	} else {
		holder = (ViewHolder) convertView.getTag();
	}

	//DateFormat dfDate = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
   	//DateFormat dfTime = DateFormat.getTimeInstance(DateFormat.LONG, Locale.FRANCE);
   	SimpleDateFormat sdfTime = new SimpleDateFormat("HH'h'mm");
   	SimpleDateFormat sdfDate = new SimpleDateFormat("dd/MM/yyyy");
   	SimpleDateFormat sdfDay = new SimpleDateFormat("E");

   	holder.tvDate.setText(ObjectToDay.displayDay(sdfDay.format(new Date(lstRagot.get(position).getDate()*1000))) + " " + sdfDate.format(new Date(lstRagot.get(position).getDate()*1000)));
   	holder.tvTime.setText(sdfTime.format(new Date(lstRagot.get(position).getDate()*1000)));
	//holder.tvPseudo.setText(lstRagot.get(position).getPseudo());
	holder.tvRagot.setText(Html.fromHtml("<b>" + lstRagot.get(position).getPseudo() + ":</b> " + lstRagot.get(position).getRagotAfterParse(), 
			new ImageGetter() {
				public Drawable getDrawable(String source) {
					Drawable bmp = null;
						if (source.equals("smile.png"))
							bmp = inflater.getContext().getResources().getDrawable(R.drawable.smile);
						if (source.equals("lien.png"))
							bmp = inflater.getContext().getResources().getDrawable(R.drawable.lien);
						if (source.equals("coeur.png"))
							bmp = inflater.getContext().getResources().getDrawable(R.drawable.coeur);
					bmp.setBounds(0,0,bmp.getIntrinsicWidth(), bmp.getIntrinsicHeight());
					return bmp;
				}
			}
	,null));

	int ecart = (firstHistory - lstRagot.get(position).getHistory()) * NBR_STEP;
	if (ecart > NBR_ECHELON * NBR_STEP)
		ecart = NBR_ECHELON * NBR_STEP;

	holder.ll.setBackgroundColor(Color.argb(127, R_COLOR[ecart], V_COLOR[ecart], B_COLOR[ecart]));

	if (!lstRagot.get(position).getJustDate()) {
		holder.tvDate.setVisibility(View.GONE);
		if (position < lstRagot.size() - 1) {
			if (!lstRagot.get(position + 1).getJustDate()) {
				holder.ivCoinHautGauche.setVisibility(View.GONE);
				holder.ivCoinHautDroite.setVisibility(View.GONE);
				holder.ivCoinBasGauche.setVisibility(View.GONE);
				holder.ivCoinBasDroite.setVisibility(View.GONE);
			}
			else {
				holder.ivCoinHautGauche.setVisibility(View.GONE);
				holder.ivCoinHautDroite.setVisibility(View.GONE);
				holder.ivCoinBasGauche.setVisibility(View.VISIBLE);
				holder.ivCoinBasDroite.setVisibility(View.VISIBLE);
			}
		}
		else {
			holder.ivCoinHautGauche.setVisibility(View.GONE);
			holder.ivCoinHautDroite.setVisibility(View.GONE);
			holder.ivCoinBasGauche.setVisibility(View.VISIBLE);
			holder.ivCoinBasDroite.setVisibility(View.VISIBLE);
		}
	}
	else {
		holder.tvDate.setVisibility(View.VISIBLE);
		holder.ivCoinHautGauche.setVisibility(View.VISIBLE);
		holder.ivCoinHautDroite.setVisibility(View.VISIBLE);
		if (position < lstRagot.size() - 1) {
			if (lstRagot.get(position + 1).getJustDate()) {
				holder.ivCoinBasGauche.setVisibility(View.VISIBLE);
				holder.ivCoinBasDroite.setVisibility(View.VISIBLE);	
			}
			else {
				holder.ivCoinBasGauche.setVisibility(View.GONE);
				holder.ivCoinBasDroite.setVisibility(View.GONE);
			}
		}
		else {
		holder.ivCoinBasGauche.setVisibility(View.VISIBLE);
		holder.ivCoinBasDroite.setVisibility(View.VISIBLE);
		}
	}
return convertView;
}
}

Ainsi que mon fichier XML :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="vertical"
android:background="@drawable/fond_date_ragot"
android:focusableInTouchMode="true"
android:focusable="true">
 <LinearLayout
       android:orientation="horizontal"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content">
    <EditText android:id="@+id/etRagot"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
               android:layout_weight="1"
               android:layout_gravity="bottom"
               android:text="IPQ..."
               android:inputType="textMultiLine"
               android:scrollHorizontally="false"
               android:nextFocusUp="@+id/etRagot" android:nextFocusLeft="@+id/etRagot"/>
    <Button android:id="@+id/bRagot"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:text="c==8"
    	/>
   </LinearLayout>

<ListView
	android:id="@+id/lvRagots"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
 android:cacheColorHint="#ffffffff"
 android:background="#ffffffff">
</ListView>

</LinearLayout>


Cordialement :)

Partager ce message


Lien à poster
Partager sur d’autres sites

En fait, je croie que c'est justement parce que j'ajoute des élements à ma liste d'item DANS le getView que ça plante. je fait le même genre d'opération dans une autre de mes activités mais là, l'ajout se faisait hors du getView, dans un onClick plus précisément.

Je pense que je vais répondre à ce problème en créant un thread qui appelera cet ajout après la fin de la résolution de mon getView.

Un peut dans ce style :

getView() {
take semaphore();

//Code ...

new Thread();

give semaphore();
}

thread() {
takeSemaphore () //restera donc bloquant...

addItemDansListView();

give semaphore()
}

Qu'est ce que vous en pensez ?

Partager ce message


Lien à poster
Partager sur d’autres sites

J'ai tenté ça :

static boolean semaphore = false;

public View getView(int position, View convertView, ViewGroup parent) {
	if (ifNotAllLoad)
		if (position == lstRagot.size() - 1) {
			semaphore = true;
			new Thread() {
	       		@Override public void run() {
	       			while (semaphore);
	       			ifNotAllLoad = myRagots.loadOldRagot();
	       	      }
	       	  }.start();
		}

	//CODE...

	semaphore = false;
	return convertView;
}

Inutile de vous dire... Il n'a pas du tout aimé... ^^ Quelqu'un a une autre idée ? Je sèche...

L'erreur c'est : Fatal exception: thread-11

Partager ce message


Lien à poster
Partager sur d’autres sites

LOL, vous allez me prendre pour un taré à me répondre tout seul ^^

Bon, alors j'ai plus ou moins réussis à faire ce que je voulais.

Déjà, l'erreur du thread-11 je l'ai résolu à force de trainé sur stack Overflow.

Donc voilà mon geekage : J'ai utilisé un handler.


static boolean semaphore = false;
final Handler uiThreadCallback = new Handler();

public View getView(int position, View convertView, ViewGroup parent) {
	if (ifNotAllLoad)
		if (position == lstRagot.size() - 1) {
			semaphore = true;


			final Runnable runInUIThread = new Runnable() {
				public void run() {
					ifNotAllLoad = myRagots.loadOldRagot();
					}
			};   					


			new Thread() {
	       		@Override public void run() {
	       			Log.v("RagotAdapter", "Before");
	       			while (semaphore) {
		       			Log.v("RagotAdapter", "Between");
	       			}
	       			Log.v("RagotAdapter", "After");
					uiThreadCallback.post(runInUIThread);
	       			//ifNotAllLoad = myRagots.loadOldRagot();
	       	    }
	       	}.start();
		}

	//code...

	semaphore = false;
	return convertView;
}

Moi après, perso, je trouve ça super laid, vue qu'avec mon while je bouffe 100% de la CPU :S

Mais sinon ma listView s'agrandis bien comme je le souhaite.

Sauf que lors de l'ajout des item, la vue reviens au début de ma list et donc si quelqu'un connait un moyen pour setter la vue d'une listview à un certain numéro d'item, je suis prenneur :)

Cordialement.

Partager ce message


Lien à poster
Partager sur d’autres sites

salut,

tu ne peux pas compter les items dans la listview (avec une boucle) et rajouter +1 (ton item) après le dernier ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour,

Tu as un projet qui s'appelle endless cwac adapter qui permet de créer une liste "infinie" :

https://github.com/commonsguy/cwac-endless

En gros dès que l'utilisateur arrive à la fin de la liste ca charge automatiquement les X prochains élements dans ta liste.

C'est ce que j'utilise dans mon application TvShow Time si tu veux voir à quoi cela ressemble.

Partager ce message


Lien à poster
Partager sur d’autres sites

Re !

^^

Après une petite semaine de vacance, j'ai commencé à eplucher ce code (EndListAdapter). Pour le moment, il me parait un peu complexe et je ne comprend pas encore toute les mécaniques de cache, etc...

C'est pourquoi j'ai quand même cherché une deuxième méthode même si je garde cette solution en boite.

je suit tombé sur cette solution qui me parait totalement plus facile : http://stackoverflow.com/questions/1080811/android-endless-list

Je voulais savoir laquelle était la "meilleur", s'il y a une méthode meilleur que l'autre ? :) Si je pose cette question c'est que je n'aime vraiment pas mettre du code dans mon appli que je ne comprend pas.

Cordialement.

Partager ce message


Lien à poster
Partager sur d’autres sites





×
×
  • Créer...