so i had a AsyncTask with RunOnUiThread to interactively change ui elements and add TableRows the problem is on the listeners in TableRows. only one works but the others don't. this is a simple from my code
public class SearchAsync extends AsyncTask<String, String, String> {
private Context mContext;
private Activity mAct;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
public void mytask(Context context, Activity act) {
mContext = context;
mAct = act;
}
@Override
protected String doInBackground(final String... arg0) {
String sc2 = "Alpha";
mAct.runOnUiThread(new Runnable() {
@Override
public void run() {
GridLayout gey = (GridLayout) mAct.findViewById(R.id.greylayout);
TableLayout tbly = (TableLayout) mAct.findViewById(R.id.listviewtable);{
final TableRow tbro = new TableRow(mContext);
TextView tev = new TextView(mContext);
tbro.setBackground(mAct.getResources().getDrawable(R.drawable.mybgbg));
tev.setTextColor(Color.WHITE);
tev.setText(sc2);
tbro.addView(tev);
tbro.setOnClickListener(new View.OnClickListener() { // this listener doesn't work.
public void onClick(View v) {
System.out.println("yey! it works");
}
});
tbro.setOnLongClickListener(new View.OnLongClickListener(){ // this listener doesn't work too.
@Override
public boolean onLongClick(View v){
System.out.println("yey! it works too!");
return true;
}
});
tbro.setOnTouchListener(new View.OnTouchListener() { // this listener works perfectly.
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
tbro.setBackground(mAct.getResources().getDrawable(R.drawable.mybgi));
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
tbro.setBackground(mAct.getResources().getDrawable(R.drawable.mybgbg));
}
return true;
}
});
tbro.setId(R.id.layoutx1);
tbro.setLongClickable(true);
tbro.setClickable(true);
tbly.addView(tbro);
}
}
}
TableRow tete = (TableRow)mAct.findViewById(R.id.layoutx1);
});
}
catch(JSONException e){
Log.e(TAG, "Json parsing error: " + e.getMessage());
);
}
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(null);
final String rslt;
rslt = result;
mAct.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast toast = Toast.makeText(mContext, rslt, Toast.LENGTH_SHORT);
toast.show();
}
});
}
So only OnTouchListener works but the others don't.. and i don't know why. this is only a problem in runOnUiThread and runonmainthread.
i tried the code onPreExecute() method and also onPostExecute. nothing works.
but in the MainActivity it works just fine.
Thanks for reading my question.
This is happening because you are returning true
from onClick()
, which indicates to the system that you have "consumed" the event.
View.OnTouchListener | Android Developers
The touch event would happen before the click event, because an ACTION_DOWN
would trigger a touch event, but you need to have an ACTION_UP
also before you can have a click event.
When you return true
from onTouch()
, this consumes the touch event, preventing the ACTION_UP
from triggering the click event.
As a general guideline, you shouldn't use OnTouchListener
and OnClickListener
together.
It looks like you are using the OnTouchListener
only to change the background. A StateListDrawable
would be much better for that. You set the background once, and the state list takes care of the rest:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/mybgi"
android:state_pressed="true"/>
<item
android:drawable="@drawable/mybgbg"/>
</selector>