AsyncTask LayoutInflater InflateException on EditText - android

I Basicly have code
new AsyncTask<Integer, Void, View>() {
#Override
protected View doInBackground(Integer... tabIds) {
return mInflater.inflate(R.layout.layout_name, null);
}
#Override
protected void onPostExecute(View result) {
super.onPostExecute(result);
root_layout.addView(result);
}
}.execute(tabId);
layout_name.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#android:color/white" >
<EditText
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<Button
android:id="#+id/do_stuff"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
with that i get InflateException: Binary XML file line #x: Error inflating class <unknown>.
if i remove EditText it works with no problems.
I cant find the reason for it (spent 2h on it).
anyone know the reason for this?
and hopefully a solution

Instead of Using AsynTask use AsyncLayoutInflater for example :
MyClass extends Fragment implements AsyncLayoutInflater.OnInflateFinishedListener {
#Override
public void onCreate(Bundle savedInstanceState) {
new AsyncLayoutInflater(context).inflate(childViewId, parent, this);
//show progress..
}
#Override
public void onInflateFinished(View view, int resid, ViewGroup parent){
if (view != null) {
//You have inflated view to use in UI Thread.
}
}
}
Besides this it has some pitfalls:
AsyncLayoutInflater class will also handle cases for views that cannot be inflated asynchronously. Such view classes has has no handler implementation and will throw exception if you try to do inflate them in AsyncTask or Thread class (As in your case). For example EditText can be inflated in UI thread only. Will ask for looper.loop(); call.
AsyncLayoutInflater will inflate such views in UI thread and rest asynchronously.
Ultimately you cannot inflate EditText in seprate thread. This is Just a workaround for what you are trying to achieve.
Also, you can try HandlerThread for the same but won't do much good.

change both
android:layout_width="match_parent"
to
android:layout_width="wrap_content"
it might help you.

Related

setVisibility not working even in uiThread

I want to toggle visibility of some elements. I have read some Q/A that the main problem was doing this in main thread but I am running the code in runOnUiThread but not works yet:
TextView progress;
TextView registrationFailed;
Button tryAgainRegistration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.registration);
sp = this.getSharedPreferences("settings", this.MODE_PRIVATE);
progress = (TextView) findViewById(R.id.progress);
registrationFailed = (TextView) findViewById(R.id.registrationFailed);
tryAgainRegistration=(Button) findViewById(R.id.tryAgainRegistration);
Setstat(0); // For test
}
public void Setstat(final Integer a){
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("progress",a.toString()); // It shows 0 and 1 correctly
if (a == 1) {
progress.setVisibility(View.VISIBLE);
registrationFailed.setVisibility(View.GONE);
tryAgainRegistration.setVisibility(View.GONE);
} else {
progress.setVisibility(View.GONE);
registrationFailed.setVisibility(View.VISIBLE);
tryAgainRegistration.setVisibility(View.VISIBLE);
}
}
});
}
for more details this is the UI xml:
<TextView
android:id="#+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical"
android:text="Registeration in progress"
android:visibility="visible" />
<TextView
android:id="#+id/registrationFailed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical"
android:text="Registeration in progress"
android:visibility="gone" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Try again"
android:id="#+id/tryAgainRegistration"
android:visibility="gone"
/>
Try running this in on create.
Just to see if it is because of the threads or not:
findViewById(R.id.yourView).setVisibility(View.GONE);
The runOnUiThread method needs a reference to the activity.
Otherwise it doesn't know which one the UI thread is.
You might get a warning about memory leaks. If you are worried about that, google for WeakReference.
((Activity)context).runOnUiThread(new Runnable() {
My specific problem was that I had created the XML view using constrainLayout but modified it manually without removing original settings of constrainLayout. So I guess the layout was not well recognized by system Ui.
In fact I made a mistake by manually renaming android.support.constraint.ConstraintLayout to LinearLayout as the root element.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".Registration"
tools:showIn="#layout/activity_registration">

Android ProgressBar styled like progress view in SwipeRefreshLayout

I use android.support.v4.widget.SwipeRefreshLayout in my Android app. It wraps a ListView. The content of the list view is downloaded from a server.
A progress view is shown when user swipes down in order to reload data from server. The progress view looks like a piece of circle that grows and shrinks during the animation. It seems that the style of this progress view cannot be customized much. However, I am fine with its built-in style.
I also show the same progress animation during initial data loading. This can be achieved by calling mySwipeRefreshLayout.setRefreshing(true). That's perfectly OK too.
However, I would like to show the same progress indication through the whole app. Consider e.g. another activity that looks like a form with submit button. There is neither a ListView nor a SwipeRefreshLayout in this form activity. Some progress indication should be displayed while the submitted data are transferred to the server. I want to show a progress bar with the same animation like in SwipeRefreshLayout.
Is there a simple and clean way to have the same progress indicator for both a SwipeRefreshLayout and a form activity that does not contain any list view and refresh layout and does not support any swipe gesture?
Thanks.
However, I would like to show the same progress indication through the
whole app. Consider e.g. another activity that looks like a form with
submit button. There is neither a ListView nor a SwipeRefreshLayout in
this form activity. Some progress indication should be displayed while
the submitted data are transferred to the server. I want to show a
progress bar with the same animation like in SwipeRefreshLayout.
yes you can use SwipeRefreshLayout to show like ProgressDialog when button click. check below.
i have added SwipeRefreshLayout inside my layout file still there is not ListView or ScrollView. just like below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="niu.com.djandroid.jdroid.androidstack.MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/activity_main_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="54dp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
now in my activity i used AsyncTask to show SwipeRefreshLayout. also use mSwipeRefreshLayout.setOnRefreshListener(null) to stop swipe gesture.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
mSwipeRefreshLayout.setOnRefreshListener(null);
((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// mSwipeRefreshLayout.setRefreshing(true);
// call AsyncTask
new LongOperation().execute("");
}
});
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
// stop mSwipeRefreshLayout
mSwipeRefreshLayout.setRefreshing(false);
}
#Override
protected void onPreExecute() {
// start mSwipeRefreshLayout
mSwipeRefreshLayout.setRefreshing(true);
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
EDITED:15/02/20
After 4 year, Here is great explanation on android developer site
mSwipeRefreshLayout.setOnRefreshListener(null)
didn't work for me, so I made this method to enable and disable refreshing.
private void setToRefresh(boolean refresh) {
if (refresh) {
mSwipeRefreshLayout.setEnabled(true);
mSwipeRefreshLayout.setRefreshing(true);
} else {
mSwipeRefreshLayout.setRefreshing(false);
mSwipeRefreshLayout.setEnabled(false);
}
}

Context changes to null outside of onCreateView method in a fragment

I am relatively new to Android. I am writing an app that uses a fragment in the main activity. This fragment also acts like a location listener and implements the onLocationChange method. This is because, based on location changes new text views are being added to this fragment.
The onCreateView method in the fragment has its scroll view created that is added to the main activity. In the same onCreateView method, I also capture the context and the linear layout tag that is present in the fragment's layout xml where I would like to insert the text views that get created in onLocationChange method.
The issue I am seeing is the context and the layout values are null in onLocationChanged method and the updateView method. Using the debugger I confirmed that they do have non-null values in the onCreateMethod only.
Here is the code snippet for the fragment class:
public class ResultsFragment extends Fragment implements LocationListener,OnCompleteListener {
private LoadPlaces loadPlaces;
HashMap<String, Double> map=new HashMap<String, Double>();
LinearLayout layout;
Context context;
Activity activity;
ScrollView view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view =(ScrollView)inflater.inflate(R.layout.scroll_view, container, false);
layout=(LinearLayout)view.findViewById(R.id.resultsView);
context=view.getContext();
return view;
}
#Override
public void onLocationChanged(final Location location) {
loadPlaces=new LoadPlaces(context); //context is null here
loadPlaces.setOnCompleteListener(this);
loadPlaces.execute(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()));
}
private void updateResultView(){
String status=loadPlaces.getResultStatus();
if("OK".equals(status)){
for (Place p:loadPlaces.getPlacesResult()){
TextView txt=new TextView(context); //context is null here
txt.setText(p.name);
txt.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
layout.addView(txt); //layout is null here
}
}
}
#Override
public void onComplete(String result) {
updateResultView();
}
here is the fragment's layout xml:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/results"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:clickable="true"
android:background="#color/grey"
android:layout_marginTop="25dip">
<LinearLayout android:id="#+id/resultsView"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
And this is the main activity's xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="30dip"
android:layout_gravity="center"
android:background="#color/background">
<fragment android:name="com.app.xxx.ResultsFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="0dp"/>
For your information, the activity that holds the fragment is never paused/killed. It is always visible while the location service runs in the background. So in this process, I don't think the fragment is getting destroyed.
Am i approaching this problem incorrectly? Is there a better way to access or save the fragment's context and use it later? Any tips will be helpful.
Thanks in advance.
Change to:
#Override
public void onLocationChanged(final Location location) {
if(getActivity()!=null){
loadPlaces=new LoadPlaces(getActivity()); //context is null here
loadPlaces.setOnCompleteListener(this);
loadPlaces.execute(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()));
}
}
The problem is location change listener is called before onCreateView.
You can ignore all the onLocationChanged calls until your fragment is attached to Activity by using above function.
public void onAttach(android.app.Activity activity) {
super.onAttach(activity);
context = (Context)getActivity();
};

handle emptylist and asynctask

I use useful guide written by Cyril Mottier there empty state of ListView inflate in ViewStub with id #android:id/empty. In this method all good, but if i have ListActivity without attached Adapter via setListAdapter or attached empty Adapter then i see empty view. It's all clear but if i want realize logic like this:
Open ListActivity
Attach adapter
Execute AcyncTask and get data for Adapter, show progress dialog
Call notifyDataSetChanged
dismiss dialog
Then from 1 to 3 steps i look empty view with error (e.g. "not found"). But I want show error only after execute AsyncTask. While during executing AsyncTask i want show only process dialog. I try play around use visibility option of #android:id/empty, try use include in xml. But can't realize this logic. Any suggestion would appreciate.
UPD: More information
I have activity.xml:
<FrameLayout
android:id="#id/gd_action_bar_content_view"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ListView
android:id="#android:id/list"
style="#style/listViewStyle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="false" />
<ViewStub
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
layout="#layout/error" />
</FrameLayout>
error.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:layout_gravity="center"
android:orientation="vertical"
android:padding="20dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="#drawable/ic_cheese" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:textStyle="bold"
android:textSize="16sp"
android:text="#string/no_cheese" />
</LinearLayout>
ListActivity Class:
public class MyListActivity extends ListActivity implements OnScrollListener, OnItemClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity); //inflate activity with ViewStub
mAdapter = new MyAdapter(this, Collections.EMPTY_LIST);
setListAdapter(mAdapter);
new SearchAndFill().execute("");
}
}
And Async class:
private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
LoadingDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
if (dialog==null){
dialog = new LoadingDialog(MyListActivity.this);
dialog.setCancelable(false);
}
dialog.show();
}
#Override
protected List<Object> doInBackground(String... str) {
return search(str[0]); //this is HTTP GET request
}
#Override
protected void onPostExecute(List<Object> result) {
super.onPostExecute(result);
dialog.dismiss();
showResult(result); //this is fill adapter data and call notifyDataSetChanged
}
}
When activity create and inflate activity.xml it's show empty with and then execute AsyncTask, while AsyncTask executing i see empty view. When call onPostExecute method of AsyncTask i see result of HTTP GET request. When activity creating and inflated activity.xml it's show empty with and then execute AsyncTask, while AsyncTask executing i see empty view. When call onPostExecute method of AsyncTask i see result of HTTP GET request. I think it's wrong. I want show blank ListView before AsyncTask executed, and after if result equals Collections.EMPTY_LIST i want show text with image (e.g nothing found)
As much as I understood this is what you want to achieve...
public class MyListActivity extends ListActivity implements OnScrollListener, OnItemClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity); //inflate activity with ViewStub
((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.GONE);
mAdapter = new MyAdapter(this, Collections.EMPTY_LIST);
setListAdapter(mAdapter);
new SearchAndFill().execute("");
}
}
... ... ....
private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
LoadingDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
if (dialog==null){
dialog = new LoadingDialog(MyListActivity.this);
dialog.setCancelable(false);
}
dialog.show();
}
#Override
protected List<Object> doInBackground(String... str) {
return search(str[0]); //this is HTTP GET request
}
#Override
protected void onPostExecute(List<Object> result) {
super.onPostExecute(result);
if (result == null || result.size() == 0){
mAdapter.notifyDataSetInvalidated();
((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.VISIBLE);
} else {
// add stuff to mAdapter here...
mAdapter.notifyDataSetChanged();
}
dialog.dismiss();
}
}
I suggest you to try setting text value of your empty view to empty string ("") then change the text value to error message when AsyncTask is complete.
Hope it solved your problem.

onItemClickListener not firing on custom ArrayAdapter

I have an Activity that retrieves data from a web service. This data is presented in a ListView via an ArrayAdapter which inflates a RelativeLayout with three TextViews inside, nothing fancy and it work fine.
Now I want to implement a Details Activity that should be called when a user clicks an item in the ListView, sounds easy but I can't for the life of me get the onItemClickListener to work on my ArrayAdapter.
This is my main Activity:
public class Schema extends Activity {
private ArrayList<Lesson> lessons = new ArrayList<Lesson>();
private static final String TAG = "Schema";
ListView lstLessons;
Integer lessonId;
// called when the activity is first created.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// can we use the custom titlebar?
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
// set the view
setContentView(R.layout.main);
// set the title
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
// listview called lstLessons
lstLessons = (ListView)findViewById(R.id.lstLessons);
// load the schema
new loadSchema().execute();
// set the click listeners
lstLessons.setOnItemClickListener(selectLesson);
}// onCreate
// declare an OnItemClickListener for the AdapterArray (this doesn't work)
private OnItemClickListener selectLesson = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int i, long l) {
Log.v(TAG, "onItemClick fired!");
}
};
private class loadSchema extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
// ui calling possible
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Schema.this,"", "Please wait...", true);
}
// no ui from this one
#Override
protected Void doInBackground(Void... arg0) {
// get some JSON, this works fine
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
// apply to list adapter
lstLessons.setAdapter(new LessonListAdapter(Schema.this, R.layout.list_item, lessons));
}
My ArrayAdapter code:
// custom ArrayAdapter for Lessons
private class LessonListAdapter extends ArrayAdapter<Lesson> {
private ArrayList<Lesson> lessons;
public LessonListAdapter(Context context, int textViewResourceId, ArrayList<Lesson> items) {
super(context, textViewResourceId, items);
this.lessons = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
}
Lesson o = lessons.get(position);
TextView tt = (TextView) v.findViewById(R.id.titletext);
TextView bt = (TextView) v.findViewById(R.id.timestarttext);
TextView rt = (TextView) v.findViewById(R.id.roomtext);
v.setClickable(true);
v.setFocusable(true);
tt.setText(o.title);
bt.setText(o.fmt_time_start);
rt.setText(o.room);
return v;
}
}// LessonListAdapter
The main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="fill_parent"
android:screenOrientation="portrait"
>
<!-- student name -->
<TextView
android:id="#+id/schema_view_student"
android:text="Name" android:padding="4dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="center_vertical|center_horizontal"
style="#style/schema_view_student"
/>
<!-- date for schema -->
<TextView
android:id="#+id/schema_view_title"
android:layout_height="wrap_content"
android:layout_margin="0dip"
style="#style/schema_view_day"
android:gravity="center_vertical|center_horizontal"
android:layout_below="#+id/schema_view_student"
android:text="Date" android:padding="6dip"
android:layout_width="fill_parent"
/>
<!-- horizontal line -->
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#55000000"
android:layout_below="#+id/schema_view_title"
/>
<!-- list of lessons -->
<ListView
android:id="#+id/lstLessons"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="#+id/schema_view_title"
/>
</RelativeLayout>
The list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="60px"
android:padding="12dip">
<TextView
android:id="#+id/timestarttext"
android:text="09:45"
style="#style/LessonTimeStartText"
android:layout_width="60dip"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="fill_parent" android:gravity="center_vertical|right" android:paddingRight="6dip"/>
<TextView
android:id="#+id/titletext"
android:text="Test"
style="#style/LessonTitleText"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_toRightOf="#+id/timestarttext"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" android:gravity="center_vertical|center_horizontal"/>
<TextView
android:id="#+id/roomtext"
android:text="123"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
style="#style/LessonRoomText"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:gravity="center_vertical" />
</RelativeLayout>
Been messing with this for the last couple of hours and I can't seem to get my head around what the problem is. My problem looks very similar to this question, but I'm not extending ListActivity, so I still don't know where my onListClickItem() should go.
UPDATE: Now I've puzzled with this for several days and still can't find the issue.
Should I rewrite the activity, this time extending ListActivity instead of Activity? Because it provides the onItemClick method itself and is probably easier to overwrite.
Or, should I bind a listener directly in each getView() in my ArrayAdapter? I believe I have read this is bad practice (I should do as I tried and failed in my post).
Found the bug - it seems to be this issue. Adding android:focusable="false" to each of the list_item.xml elements solved the issue, and the onclick is now triggered with the original code.
I've encountered the same issue and tried your fix but couldn't get it to work. What worked for me was adding android:descendantFocusability="blocksDescendants" to the <RelativeLayout> from the item layout xml, list_item.xml in your case. This allows onItemClick() to be called.
What worked for me :
1) Adding android:descendantFocusability="blocksDescendants" to Relative Layout tag.
The result is shown below :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants" >
2) Adding android:focusable="false" to every element in in list_item.xml
example :
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:focusable="false" />
Once I had a similar problem. Every list item had a text view and a checkbox, and just because the checkbox, the whole listitem wasn't 'enabled' to fire the event. I solved it by making a little trick inside the adapter when I was getting the view.
Just before returning the view I put:
v.setOnClickListener(listener);
(The object listener is an onItemClickListener I gave to the Adapter's constructor).
But I have to tell you, the problem is because the platform, it is a bug.
I had the same problem and I tried to solve it by adding
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
to my item.xml but it still doesn't work !!! Infact I found the issue in the relative layout witch contains
android:focusableInTouchMode="true" android:focusable="true"
And when I removed it All things is ok
protected void onPostExecute(Void result) {
progressDialog.dismiss(); stLessons.setAdapter(new LessonListAdapter(Schema.this, R.layout.list_item, lessons));
//add this
ListView lv = getListView(); lv.setOnItemClickListener(new ListView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int i, long l) {
//do stuff
}
});
}

Categories

Resources