2013-06-29 3 views
2

У меня есть список, элементы которого представляют собой пользовательские представления, состоящие из 2 меток и кнопки в relativelayout.ACTION_DOWN, ACTION_UP и событие onClick

При выполнении этого, «обратная связь» кнопки мыши -The списке следует пункт изменен цвет фона в то время как вы касаетесь it- пропадает, так что я решил сделать это с помощью ACTION_DOWN и ACTION_UP

я этот класс, чтобы положить в все ListViews с той же проблемой:

// The same instance of this class is setted as onTouchListener to the labels and the layout 
public class OnTouchChangeColor implements OnTouchListener { 

TransitionDrawable transition; 
private final int duration = 250; 
public static final int INITCOLOR = Color.WHITE; 
public static final int FINALCOLOR = Color.CYAN; 
// this will be the layout container of the labels and the button 
ViewGroup layout = null; 
public OnTouchChangeColor(ViewGroup layout){ 
    update(layout); 
} 

public void update(ViewGroup layout){ 
    this.layout = layout; 
    TransitionDrawable t = new TransitionDrawable(new Drawable[]{new ColorDrawable(INITCOLOR), new ColorDrawable(FINALCOLOR)}); 
    layout.setBackgroundDrawable(t); 
    transition = (TransitionDrawable) layout.getBackground(); 
} 
@Override 
public boolean onTouch(View v, MotionEvent event) { 
    int eventaction = event.getAction(); 
    switch (eventaction) { 
     case MotionEvent.ACTION_DOWN: 
     transition.startTransition(duration); 
     break; 
     case MotionEvent.ACTION_UP: 
     transition.reverseTransition(duration); 
     break; 
    } 
    // tell the system that we handled the event but a further processing is required 
    return false; 
} 

проблема заключается в том, что элемент получает сенсорную ACTION_DOWN события, но не ACTION_UP, вот: фоновые изменения от белого до голубого цвета в 250мсе, после этого он делает событие OnClick , но он не выполняет ACTION_UP ...

OnClick делает это:

@Override 
public void onClick(View v) { 
    try { 
     loadData(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    Intent intent = new Intent(context, ActDestiny.class); 
    intent.putExtra("stop", true); 
    context.startActivity(intent); 
} 

Ну: он идет к следующей деятельности, но он не ставит его фона обратно на белый ... Более того: иногда он не идет к своей судьбе, но фоновые изменения Cyan и застряли в голубом цвете ...

Я прочитал в документации андроида, что возвращение «ложь» в ontouch функции:

Итак, если вы возвращаете ложь, когда события вниз действий , вы указываете, что вы не воспользовались событием, а также не заинтересованы в т действий с этого события. Таким образом, вы не будете вызывать для каких-либо других действий внутри события, таких как жест пальца или возможное событие действия.

Так что, если я вернусь правда обратная связь работает, но событие потребляется и OnClick не работает ...

Так что я не знаю, что нужно сделать, чтобы получить «обратную связь» от прикосновения элемент и событие onclick работают ....

Я мог бы называть onClick внутри ACTION_UP, но его очень уродливое - особенно думая в событии onLongClick.

Его можно использовать ACTION_DOWN, ACTION_UP, чтобы сделать анимацию и событие onClick, чтобы сделать логику приложения сразу?

Как я могу восстановить -and costumize-обратную ссылку «нажатие кнопки»?

EDIT TO Почтовый индекс:

Ну, там запрошенный код.

XML-:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/layout_titular_mp3" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="horizontal"> 

<TextView 
    android:id="@+id/LblTitulo" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/btnAccion" 
    android:textSize="20dp" 
    android:textStyle="bold" /> 

<TextView 
    android:id="@+id/LblSubTitulo" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@id/LblTitulo" 
    android:layout_toLeftOf="@id/btnAccion" 
    android:text=" " 
    android:textSize="12dp" 
    android:textStyle="normal" /> 

<Button 
    android:id="@+id/btnAccion" 
    android:layout_width="48dp" 
    android:layout_height="wrap_content" 
    android:layout_alignParentRight="true" 
    android:background="@drawable/playbutton_style" 
    android:gravity="center_vertical|center_horizontal|right" 
    android:visibility="gone" /> 

</RelativeLayout> 

и код адаптера. Обратите внимание, что, когда я делаю это:

cvh.updateCustomOnClickBases(titActual, context,posicion); 
cvh.updateOnTouchListeners();  

Я делаю это потому, что ListView создает только мнения, которые на экране и при прокрутке его recicles тот, который выходит из (верхней) WHIT информации из следующий элемент в вашем массиве данных (который будет показан вниз, как следующий).

Таким образом, я собираю события, которые обновляют их ссылки. Код ниже.

public class AdaptPlayList extends BaseAdapter { 
private final Context context; 
ArrayList<PlayList> datos; 
long id; 

public AdaptPlayList(Context context, ArrayList<PlayList> datos, int typ) { 
    this.datos = datos; 
    this.context = context; 
} 

public void updatePlaylist(ArrayList<PlayList> pl){ 
    ThreadPreconditions.checkOnMainThread(); 
    this.datos = pl; 
    notifyDataSetChanged(); 
} 

@Override 
public int getCount(){ 
    return datos.size(); 
} 

@Override 
public PlayList getItem(int index) { 
    return datos.get(index); 
} 

@Override 
public long getItemId(int index) { 
    return index; 
} 


public View getView(int posicion, View convertView, ViewGroup parent) { 
    final PlayList titActual = getItem(posicion); 
    CancionViewHolder cvh; 
    if (convertView == null) { 
     cvh = new CancionViewHolder(); 
     convertView = LayoutInflater.from(context).inflate(R.layout.titularmp3, parent, false); 
     OnPlaylistItemClick itemClick = new OnPlaylistItemClick(titActual, context,posicion); 
     cvh.titulo = (TextView) convertView.findViewById(R.id.LblTitulo); 
     cvh.btnAction = (Button) convertView.findViewById(R.id.btnAccion); 
     cvh.layout = (ViewGroup)convertView.findViewById(R.id.layout_titular_mp3); 
     cvh.click = itemClick; 
     cvh.longClick = itemClick; 
     cvh.btnClick = new OnPlaylistButtonClick(titActual, context,posicion); 
     convertView.setTag(cvh); 
    }else{ 
     cvh = (CancionViewHolder)convertView.getTag(); 
    } 
    cvh.updateCustomOnClickBases(titActual, context,posicion); 
    cvh.updateOnTouchListeners(); 
    TextView titulo = cvh.titulo; 
    Button btnAction = cvh.btnAction; 
    titulo.setText(titActual.getDesc()); 
    btnAction.setVisibility(View.VISIBLE); 
    btnAction.setOnClickListener(cvh.btnClick); 
    titulo.setOnClickListener(cvh.click); 
    titulo.setOnLongClickListener(cvh.longClick); 
    return convertView; 

} 
} 

class OnPlaylistItemClick extends CustomOnClickBase implements OnClickListener, OnLongClickListener{ 

public OnPlaylistItemClick(PlayList pl, Context ctx, int position) { 
    super(pl, ctx, position); 
} 

@Override 
public boolean onLongClick(View v) { 
    // do things.... 
      // 
    Intent intent = new Intent(context, ActListadoCancionesAsync.class); 
    intent.putExtra("stopMusic", true); 
    context.startActivity(intent); 
    return true; 
} 

@Override 
public void onClick(View v) { 
    // do more things! 
    } 
} 

} 

class OnPlaylistButtonClick extends CustomOnClickBase implements OnClickListener{ 
PlayList titActual; 

public OnPlaylistButtonClick(PlayList pl, Context ctx, int position) { 
    super(pl, ctx, position); 
    titActual = pl; 
} 

@Override 
public void onClick(View v) { 
    // do things 
      //.... 
    Intent intent = new Intent(context, ActListadoCancionesAsync.class); 
    intent.putExtra("stopMusic", true); 
    context.startActivity(intent); 
} 
} 

С помощью этого держателя и clickbase избежать объектные творения (я построю событие слушателей элементов в ListView, что обновляемые вместо создания новых слушателей)

public class CancionViewHolder{ 
    public TextView titulo; 
    public TextView subtitulo; 
    public ToggleButton button; 
    public Button btnAction; 
    public OnClickListener btnClick; 
    public OnClickListener click; 
    public OnLongClickListener longClick; 
    public ViewGroup layout = null; 

    /**Actualiza los eventos que estan cacheados para que apunten a sus nuevos contenidos del adapter. De otro modo, como los 
    * datos del adapter se moveran mientras que los views seran reutilizados los eventos apuntarian a la anterior posicion 
    * @param datosItem 
    * @param ctx 
    * @param pos 
    */ 
    public void updateCustomOnClickBases(Object datosItem, Context ctx, int pos){ 
     ((CustomOnClickBase)click).updateObject(datosItem, ctx,pos, layout); 
     ((CustomOnClickBase)longClick).updateObject(datosItem, ctx,pos, layout); 
     ((CustomOnClickBase)btnClick).updateObject(datosItem, ctx,pos, layout); 
    } 

    /** 
    * Establece los listeners que hacen efectos cuando se pulsa algo 
    */ 
    public void updateOnTouchListeners() { 
     if (layout != null) { 
      OnTouchChangeColor cc = new OnTouchChangeColor(layout); 
      layout.setOnTouchListener(cc); 
      if (subtitulo != null){ 
       subtitulo.setOnTouchListener(cc); 
      } 
      if (titulo != null){ 
       titulo.setOnTouchListener(cc); 
      } 
     } 
    } 
} 

И

public abstract class CustomOnClickBase { 
protected Object datosItem; 
protected Context context; 
protected int position; 
protected ViewGroup layout; 

public CustomOnClickBase(Object datosItem, Context ctx, int position){ 
    updateObject(datosItem, ctx, position, layout); 
} 

public void updateObject(Object datosItem, Context ctx, int position, ViewGroup layout){ 
    this.datosItem = datosItem; 
    context =ctx; 
    this.position = position; 
    this.layout = layout; 
} 
} 
+0

Возможно, что-то не так с вашим расположением элементов списка или тем, как вы настраиваете представление через свой адаптер. Обратная связь касания для элементов списка не должна отличаться от любой другой компоновки. Можете ли вы разместить свой элемент списка XML и код вашего адаптера? – kcoppock

+0

Я разместил код ... Вы должны быть абсолютно ... Я помню, что обратная связь исчезла, когда я переместил обработку событий из активности (через listView.setOnItemClickListener ... и т. Д.) В адаптер через view.setOnClickListeners ... и т.п. – inigoD

ответ

1

Я думаю, вам нужно изменить свой метод onTouch()

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    int eventaction = event.getAction(); 
    switch (eventaction) { 
     case MotionEvent.ACTION_DOWN: 
     transition.startTransition(duration); 
     //Tell Android that you can handle this MotionEvent, and you 
     //want to keep informed of further events of this touch 
     return true; 
     break; 
     case MotionEvent.ACTION_UP: 
     transition.reverseTransition(duration); 
     break; 
    } 
    // tell the system that we handled the event but a further processing is required 
    return false; 
} 

Надеюсь, что это поможет.

0
public boolean onTouch(MotionEvent ev) { 
... 
return super.onTouch(ev); 
} 

Возможно, вы не должны возвращать false самостоятельно.

Смежные вопросы