Autore Topic: ListView con elementi switchabili stile rubrica  (Letto 138 volte)

Offline SalvoCt

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Tablet Asus
  • Sistema operativo:
    Windows 7
ListView con elementi switchabili stile rubrica
« il: 03 Febbraio 2012, 12:17:09 CET »
0
Salve a tutti! sono nuovo del forum! Volevo sottoporvi un mio problema, sperando che mi possiate illumiare ;-).
Voglio realizzare una lista di prodotti dove ogni elemento ha la possibilità di "spostarsi" a destra o a sinistra, come gli elementi della rubrica per intenderci.

Il mio approccio è quello di personalizzare l'evento onFling ma non so come procedere! Inoltre mi sono accorto che con l'utilizzo dell'adapter gli indici non sono univoci!


Cioè se faccio
Codice (Java): [Seleziona]
 View item= getChildAt(index_selected);
 item.setBackgroundColor(Color.argb(125, 255, 0, 0));
Mi cambia il background di più elementi!

Sposto l'intero codice per completezza :)
Codice (Java): [Seleziona]
public class ListViewProduct extends ListView{
       
        public Context context;
        private MyGestureListener myGestureListener;
        public int index_selected=0;
    private int startPosition,endPosition;
        public ListViewProduct(Context context) {
               
                super(context);
                this.context=context;
                 myGestureListener = new MyGestureListener(this.context);
                this.setOnTouchListener(myGestureListener);
                setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                // TODO Auto-generated constructor stub
        }
       
        public ListViewProduct(Context context,AttributeSet att)
        {
                super(context,att);
                this.context=context;
                 myGestureListener = new MyGestureListener(this.context);
                this.setOnTouchListener(myGestureListener);
                setChoiceMode(ListView.CHOICE_MODE_SINGLE);
               
        }
       
        @Override
        public boolean onTouchEvent(MotionEvent e)
        {
                switch(e.getAction())
                {
               
                case MotionEvent.ACTION_DOWN:
                        startPosition=this.pointToPosition((int)e.getX(),(int) e.getY());
                        Log.i("start position",""+startPosition);
                        if(startPosition!=this.INVALID_POSITION)
                                index_selected=startPosition-this.getFirstVisiblePosition();
                        break;
                       
                }
                return super.onTouchEvent(e);
               
        }
        class MyGestureListener extends SimpleOnGestureListener implements OnTouchListener
    {
        Context context;
        GestureDetector gDetector;
        private static final int SWIPE_MIN_DISTANCE = 160;
        // Distanza massima consentita sull'asse Y
        private static final int SWIPE_MAX_OFF_PATH = 400;
        // Velocità minima richiesta sull'asse X
        private static final int SWIPE_THRESHOLD_VELOCITY = 150;
        public MyGestureListener()
        {
            super();
        }

        public MyGestureListener(Context context) {
            this(context, null);
        }

        public MyGestureListener(Context context, GestureDetector gDetector) {

            if(gDetector == null)
                gDetector = new GestureDetector(context, this);

            this.context = context;
            this.gDetector = gDetector;
        }


        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

                try {
                if (Math.abs(e1.getY() - e2.getY()) > dp2px(SWIPE_MAX_OFF_PATH))
                        return false;
                // Swipe da destra a sinistra
                if (e1.getX() - e2.getX() > dp2px(SWIPE_MIN_DISTANCE)
                                && Math.abs(velocityX) > dp2px(SWIPE_THRESHOLD_VELOCITY)) {
                         
                        Log.i("seleziono ",""+index_selected);
                            View item= getChildAt(index_selected);
                             
                             item.setBackgroundColor(Color.argb(125, 255, 0, 0));
                             
                        Toast.makeText(context, "Swipe a sinistra", Toast.LENGTH_SHORT).show();
                } else if (e2.getX() - e1.getX() > dp2px(SWIPE_MIN_DISTANCE)
                                && Math.abs(velocityX) > dp2px(SWIPE_THRESHOLD_VELOCITY)) {
                       
                            View item= getChildAt(index_selected);
                        item.setBackgroundColor(Color.argb(125, 0, 255, 0));
                        Toast.makeText(context, "Swipe a destra", Toast.LENGTH_SHORT).show();
                }
        } catch (Exception e) {
               
        }
        return false;
}
       

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {

            return super.onSingleTapConfirmed(e);
        }
       
        public float dp2px(int dip) {
            float scale = getResources().getDisplayMetrics().density;
            return dip * scale + 0.5f;
    }

       
        public boolean onTouch(View v, MotionEvent event) {

               
            return gDetector.onTouchEvent(event);
        }


        public GestureDetector getDetector()
        {
            return gDetector;
        }      
    }
       

}


E l'adapter relativo!
Codice (Java): [Seleziona]
public class ListAdapterProduct extends BaseAdapter{
       
       
        ArrayList<HashMap<String, Object>> data=new ArrayList<HashMap<String,Object>>();
       
        public boolean itemsEnable;
        private Context context;
        private Typeface face;
        private int color;
        private int size;
        private LayoutInflater inflater;
        private boolean isAllEnable;
       
        public ListAdapterProduct(Context c,Typeface face,int color,int size)
        {
                context=c;
                this.face=face;
                this.color=color;
                this.size=size;
                this.isAllEnable=true;
                this.inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

       
       
        public void setAllEnable(boolean enable){this.isAllEnable=enable; this.notifyDataSetChanged();}
       
        @Override
        public boolean isEnabled(int position)
        {
          return this.isAllEnable;
        }
       
        public int getCount() {
                // TODO Auto-generated method stub
                return data.size();
        }

        public Object getItem(int arg0) {
                // TODO Auto-generated method stub
                return data.get(arg0);
        }

        public long getItemId(int arg0) {
                // TODO Auto-generated method stub
                return arg0;
        }

        public void addItem(HashMap<String,Object> row)
        {
                data.add(row);
                this.notifyDataSetChanged();
        }
        public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder=null;
               
                if(convertView==null)
                {
                        convertView=inflater.inflate(R.layout.single_item_list, null);
                       
                        holder=new ViewHolder();
                        holder.code=(TextView)convertView.findViewById(R.id.code);
                        holder.desc=(TextView)convertView.findViewById(R.id.name);
                        convertView.setTag(holder);
                }
                else
                {
                        holder=(ViewHolder)convertView.getTag();
                }
               
                holder.code.setText(data.get(position).get("code").toString());

                holder.code.setTypeface(this.face);
                holder.code.setTextColor(this.color);
                holder.code.setTextSize(this.size);
               
                holder.desc.setText(data.get(position).get("name").toString());
           
                holder.desc.setTypeface(this.face);
                holder.desc.setTextColor(this.color);
                holder.desc.setTextSize(this.size);
               
                return convertView;
        }
       
        class ViewHolder
        {
                public TextView code;
                public TextView desc;
        }

       

}

Il dispositivo di riferimento è un Tablet con Android 3.2.1!
Grazie a chiunque risponderà!


Offline SalvoCt

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Tablet Asus
  • Sistema operativo:
    Windows 7
Re:ListView con elementi switchabili stile rubrica
« Risposta #1 il: 06 Febbraio 2012, 17:51:40 CET »
0
Nessuno mi può dare una mano? :-(

Offline blackgin

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1063
  • Respect: +116
    • Google+
    • blackgins
    • blackginsoft
    • Mostra profilo
    • CommaBit
  • Dispositivo Android:
    Galaxy Nexus
  • Market Developer Name:
    CommaBit
  • Sistema operativo:
    Mac OSX
R: ListView con elementi switchabili stile rubrica
« Risposta #2 il: 06 Febbraio 2012, 21:23:17 CET »
0
Io non ho ben capito cosa vuoi fare
Fate i bravi bimbi, postatelo il LogCat

Offline SalvoCt

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Tablet Asus
  • Sistema operativo:
    Windows 7

Offline Verandi

  • Moderatore globale
  • Utente normale
  • *****
  • Post: 378
  • Respect: +74
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:ListView con elementi switchabili stile rubrica
« Risposta #4 il: 07 Febbraio 2012, 09:35:23 CET »
0
Il problema del background è dovuto al riciclo delle view dell'adapter, per cui, se setti il background della view in una posizione x, verrà cambiato anche il background in tutte le posizioni in cui quella view verrà riciclata.
Per far sì che cambi solo il background della riga che vuoi, devi aggiungere un array in cui salvi la posizione della riga e, nel getview() dell'adapter controllare in che posizione della lista ti trovi e settare il background di conseguenza.
Se vuoi spostare a destra/sinistra la riga dopo una certa azione, credo tu debba usare un'animazione e usare lo stesso principio dell'array, altrimenti ti ritrovi con l'animazione applicata a più righe. Nel caso, invece, tu voglia spostare la riga a mano a mano che sposti il dito, puoi usare il metodo setX() della classe View, visto che usi un'api >=11, altrimenti mi pare si possa giocare sui margini.

Offline SalvoCt

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Tablet Asus
  • Sistema operativo:
    Windows 7
Re:ListView con elementi switchabili stile rubrica
« Risposta #5 il: 07 Febbraio 2012, 10:38:32 CET »
0
Il problema del background è dovuto al riciclo delle view dell'adapter, per cui, se setti il background della view in una posizione x, verrà cambiato anche il background in tutte le posizioni in cui quella view verrà riciclata.
Per far sì che cambi solo il background della riga che vuoi, devi aggiungere un array in cui salvi la posizione della riga e, nel getview() dell'adapter controllare in che posizione della lista ti trovi e settare il background di conseguenza.
Se vuoi spostare a destra/sinistra la riga dopo una certa azione, credo tu debba usare un'animazione e usare lo stesso principio dell'array, altrimenti ti ritrovi con l'animazione applicata a più righe. Nel caso, invece, tu voglia spostare la riga a mano a mano che sposti il dito, puoi usare il metodo setX() della classe View, visto che usi un'api >=11, altrimenti mi pare si possa giocare sui margini.

Grazie per i consigli!! :) Allora il problema del background l'ho risolto mettendo uno stato per la view (-1,0,1) e in base a esso setto il colore appropriato.
Adesso devo implementare il "trascinamento" speriamo bene !! :D