2013-06-29 42 views
2

我有一个列表视图,其中的项目是由2个标签和一个相关布局中的按钮组成的自定义视图。ACTION_DOWN,ACTION_UP和onClick事件

在这样做时,该列表视图按钮点击-the项目的“反馈”改变背景颜色,而你触摸它 - 自败,所以我决定用它和ACTION_DOWN ACTION_UP

我没有这个类就摆在做具有相同问题的所有列表视图:

// 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); 
} 

好:它进入到下一个活动,但它并没有把它的背景白回来......不仅如此:有时它不走自己的命运,但背景变为青色和卡在青...

我读过Android文档在返回的ontouch功能“假”:

所以,如果你返回false当向下动作事件已收到,您表示您没有消费过该事件,并且对后续事件也不感兴趣t来自这个事件的行动。因此,您不会被要求在事件内执行任何其他操作,例如手指手势或最终向上操作事件。

所以,如果我返回true反馈工作,但该事件被消耗的onclick不工作...

所以我不知道该怎么做才能让触摸的“反馈”一个项目和onclick事件....

我可以调用ACTION_UP内的onClick,但它非常丑 - 尤其是'onLongClick'事件中的想法。

它有可能使用ACTION_DOWN,ACTION_UP来制作动画和onClick事件来一次制作应用程序的逻辑?

我该如何恢复 - 并且成本低 - “按下按钮”的反馈?

编辑到邮政编码:

那么,有要求的代码。

的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丝毫的的信息是走出一个(上一个)的意见您的数据阵列中的下一项(将显示为下一项)。

所以我赞扬了事件监听者也更新他们的引用。代码如下。

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

我发布了代码...您必须是严格的...我记得当我通过view.setOnClickListeners将事件处理从活动(通过listView.setOnItemClickListener ...等)移动到适配器时,反馈消失...等等 – 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); 
} 

也许你不应该自己回来。

相关问题