Dynamic questionnaire in Android - android

i want to make a questionnaire with Android Studio. Each question can be answered with yes or no. The problem is, that i have some follow-up questions (f.e. if question 1 answered with yes, then i have 3 follow-up questions to answer). Maybe it is important to know, that there are only follow-up questions if the user is clicking on the yes Button for some questions (there are never follow-up questions if he is clicking no)
I am an absolute beginner, so tell me if you have other ideas to solve this problem.
My idea is to make a custom listview and if the user is clicking on the first answer, i want to update the list and add questions if they are needed now (would be ok if the new questions are getting to the end of the list).
That's my Code till now:
questions_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/questionsListView"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:descendantFocusability="blocksDescendants"/>
</RelativeLayout>
itemView.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/question"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<RadioGroup
android:orientation="horizontal"
android:id="#+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_below="#+id/question">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yes"
android:id="#+id/yesButton"
android:layout_marginLeft="135dp" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No"
android:id="#+id/noButton"
android:layout_marginRight="50dp"/>
</RadioGroup>
</RelativeLayout>
LoggedInActivity.java:
public class LoggedInActivity extends Activity {
public List<Questions> myquestions = new ArrayList<Questions>();
public List<Integer> answerList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.questions_activity);
populateQuestions();
populateListView();
registerClickCallback();
}
private void registerClickCallback(){
ListView list = (ListView) findViewById(R.id.questionsListView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
boolean clickedQuestion = myquestions.get(position).getAnswer();
}
});
}
private void populateQuestions() {
myquestions.add(new Questions("Question1"));
myquestions.add(new Questions("Question2"));
myquestions.add(new Questions("Question3"));
}
private void populateListView() {
ArrayAdapter<Questions> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.questionsListView);
list.setAdapter(adapter);
}
private class MyListAdapter extends ArrayAdapter<Questions> {
public MyListAdapter() {
super(LoggedInActivity.this, R.layout.item_view, myquestions);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
itemView = getLayoutInflater().inflate(R.layout.item_view, parent, false);
}
Questions currentQuestion = myquestions.get(position);
TextView question = (TextView) itemView.findViewById(R.id.question);
question.setText(currentQuestion.getQuestion());
RadioGroup answers = (RadioGroup) itemView.findViewById(R.id.radioGroup);
return itemView;
}
}
The OnClickListener doesn't work at all. I know, i need to do something with the RadioGroup in getView, but i don't know how (already tried to progress with solutions from here(Customized ListView with TextView, TextView, RadioGroup in Android) but it doesn't worked.
Is it even possible to add new questions and delete them if he is changing his opinion or are there better solutions?

I would offer you solutions on the onClick Listener part
Try any of the following steps
1. Try making use of your onClick listener in the onCreate method directly
2 You can implement View.OnClickListener, after that you create an onclick method. Inside the onclick method you can now perform any action you wish to perform

Related

Android - OnItemClickListener only *sometimes* not working

I have a ListView in one of my activities that I have bound to an ArrayList using a custom ArrayAdapter. I have set an OnItemClickListener to the ListView which should call a method that starts another activity. However, I find that when I click on the ListView items, it only sometimes works. Sometimes it will start the activity as it should; other times it seems to detect the click (the ripple effect appears on the list item) but does nothing; other times it doesn't even appear to detect the click (the ripple effect doesn't appear).
I've tried all the usual suggestions that I've come across: blocking descendants on the parent view item, setting clickable and focusable to false on all the components of the item views, setting isEnabled to return true in the custom adapter, etc, but the behavior remains the same. Any help appreciated. Here is the relevant code:
Activity containing the ListView:
public class ViewCollectionActivity extends AppCompatActivity {
private final String className = this.getClass().getSimpleName();
private CollectionHandler collectionHandler;
private Context context;
private ArrayList<Game> displayedCollection;
private GameCollectionAdapter collectionAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_collection);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
context = this;
collectionHandler = CollectionHandler.getInstance(this);
TextView view = null;
if (collectionHandler.getDisplayedCollection().size() > 0) {
view = (TextView) findViewById(R.id.no_items_textview);
view.setVisibility(View.GONE);
}
String currentDate = collectionHandler.getDateLastSynchronised();
view = (TextView) findViewById(R.id.last_updated_textview);
view.setText("Last synchronised: " + currentDate + " Total games: " + String.valueOf(collectionHandler.getDisplayedCollection().size()));
collectionAdapter = collectionHandler.getCollectionAdapter();
ListView listView = (ListView) findViewById(R.id.collection_list_view);
listView.setAdapter(collectionAdapter);
AdapterView.OnItemClickListener collectionItemClickListener = new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
launchGameDetailsActivity(position);
}
};
listView.setOnItemClickListener(collectionItemClickListener);
}
public void launchGameDetailsActivity(int position){
Log.d(className,"Starting lauchGameDetailsActivity method");
collectionHandler.setSelectedGame(position);
Intent intent = new Intent(this,ViewGameDetailsActivity.class);
startActivity(intent);
Log.d(className, "Ending lauchGameDetailsActivity method");
}
The XML for the activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.bleachedlizard.ludome.viewcollection.ViewCollectionActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Synchronise Collection"
android:onClick="synchroniseCollection"/>
<TextView
android:id="#+id/last_updated_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Last synchronised: "
android:textAlignment="center"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Display Collection"
android:visibility="gone"
android:onClick="displayCollection"/>
<ListView
android:id="#+id/collection_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/no_items_textview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="You have no items in your collection."
android:textAlignment="center"
android:textSize="20sp"/>
</LinearLayout>
The XML for the item views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/collection_item_layout"
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"
android:clickable="false"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="#+id/collection_item_image"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="#drawable/testimage"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
/>
<TextView
android:id="#+id/collection_item_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:padding="16dp"
android:singleLine="false"
android:textColor="#android:color/darker_gray"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
<TextView
android:id="#+id/collection_item_plays"
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="8dp"
android:textColor="#android:color/darker_gray"
android:text="Plays: 0"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
</LinearLayout>
The code for the custom adapter:
public class GameCollectionAdapter extends ArrayAdapter<Game> {
private ArrayList<Game> collection;
public GameCollectionAdapter(Context context, int resource, ArrayList<Game> collection){
super(context, resource, collection);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout gameView = (LinearLayout) convertView;
LayoutInflater mInflater = LayoutInflater.from(getContext());
if (gameView == null) {
gameView = (LinearLayout) mInflater.inflate(R.layout.collection_item_view, null);
}
//Game game = collection.get(position);
Game game = super.getItem(position);
if (game != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView gameTitle = (TextView) gameView.findViewById(R.id.collection_item_name);
TextView numOfPlays = (TextView) gameView.findViewById(R.id.collection_item_plays);
ImageView thumbnail = (ImageView) gameView.findViewById(R.id.collection_item_image);
// check to see if each individual textview is null.
// if not, assign some text!
if (gameTitle != null){
gameTitle.setText(game.getTitle());
}
if (numOfPlays != null){
numOfPlays.setText("Plays: " + String.valueOf(game.getNumOfPlays()));
}
if (thumbnail != null){
thumbnail.setImageBitmap(game.getThumbnail());
}
}
// the view must be returned to our activity
return gameView;
}
#Override
public boolean isEnabled(int position) {
return true;
}
}
I discovered what was causing the problem: the way I had set up the array that backed the ListView meant that it was downloading and storing the Bitmaps for every element in the array all the time. Once I changed the implementation so that it only downloaded the images as the ListView required them, then that seemed to improve performance and the onClickListener started to work fine.
The implementation I used was the exact same one shown here:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
I think the issue is due to the position of the item selection whenever you click you have an list position which is passed to your method launchGameDetailActivity(int position) check with log or toast on item click what all the position you are getting do the needful.
Here is my code try this like this if it helps.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(RecipeClass.this, "Position is" + position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RecipeClass.this, RecipeIngredients.class)
intent.putExtra("position", position);
startActivity(intent);
}
Check your arraylist value also whether they are not null.

How to inflate a ListView to a View

I'm new here so i will try to explain my problems as good as i can.
I am trying to inflate a ListView into a View in my main activity. My main activity has some buttons and texts on the top of the Activity and there is enough space left for the listView. The listview is consisted of categories, represented as an imageView and a textview.
The problem im facing is that when i inflate the category_list_activity, the activity i created for the category list, two things happen:
The ListView takes over all the screen, which means i cannot touch neither the buttons nor the edittext, and also the ListView is empty.
I have created the Adapters needed and i have searched for some info here in stackof but i couldn't find any right answer.
Edit: due to solving the problem when the list was taking over the whole screen i remove the parts of code that is not needed.
The solution was to change the inflated activity's (activity_category_list.xml) height from "fill_parent" to "wrap_content". I also restricted the show code to the parts i think there is the problem about not loading the categories.
here is the parts of code i wrote:
MainActivity.java
public class MainActivity extends ActionBarActivity {
Activity a;
Button toogle_button;
Button go_button;
Button login_button;
EditText search_text;
View inflating_view;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
a = this;
inflating_view = findViewById(R.id.inflating_view);
ViewGroup parent =(ViewGroup) inflating_view.getParent();
int index = parent.indexOfChild(inflating_view);
parent.removeView(inflating_view);
inflating_view = getLayoutInflater().inflate(R.layout.activity_category_list, parent, false);
parent.addView(inflating_view, index);
inflating_view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast t = Toast.makeText(getApplicationContext(), "ListView clicked", Toast.LENGTH_SHORT);
t.show();
}
});
}
CategoryAdapter.java
private class Viewholder{
TextView category_text;
ImageView image;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Viewholder holder = null;
Category category = categories.get(position);
if (convertView == null){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = (View) inflater.inflate(R.layout.activity_category, null);
holder = new Viewholder();
holder.category_text = (TextView) convertView.findViewById(R.id.category_text);
holder.image = (ImageView) convertView.findViewById(R.id.category_image);
convertView.setTag(holder);
}else{
holder = (Viewholder) convertView.getTag();
}
holder.category_text.setText(category.getName());
holder.image.setImageURI(category.getImageUri());
return convertView;
}
}
CategoryListActivity.java
public class CategoryListActivity extends ActionBarActivity {
ListView category_list_view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category_list);
Log.d("Category List View", "Category list view is called");
category_list_view = (ListView) findViewById(R.id.category_list_view);
CategoryAdapter ca = new CategoryAdapter(getApplicationContext(),
TestValues.categories);
category_list_view.setAdapter(ca);
category_list_view.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Clicked Category" + parent.getItemIdAtPosition(position), Toast.LENGTH_LONG);
toast.show();
}
});
Log.d("Category List View", "Everything is loaded");
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
style="#android:style/Theme.Black.NoTitleBar"
tools:context="com.example.aggro.activities.MainActivity" >
<Button
android:id="#+id/toggle_button"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:text="#string/toogle_list_en"
android:textSize="10dp"
/>
<TextView
android:id="#+id/search_text_view"
android:layout_toRightOf="#+id/toggle_button"
android:layout_alignParentTop="true"
android:text="#string/search_text_en"
android:layout_height="30dp"
android:paddingTop="7dp"
android:textSize="10dp"
android:textColor="#FFFFFF"
android:layout_width="wrap_content"/>
<EditText
android:id="#+id/search_text"
android:layout_width="150dp"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:background="#000000"
android:layout_toLeftOf="#+id/search_go"
android:layout_toRightOf="#+id/search_text_view" />
<Button
android:id="#+id/search_go"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_toLeftOf="#+id/login_button"
android:layout_alignParentTop="true"
android:text="#string/search_go_en"
android:textSize="10dp" />
<Button
android:id="#+id/login_button"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="#string/login_en"
android:textSize="10dp" />
<View
android:id="#+id/inflating_view"
android:layout_below="#+id/toggle_button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
I have checked the CategoryListActivity.java alone and it works as it was supposed to, so i think the adapter works right.
If you need any other information please let me know.
Thanks in advance.
Why are you using View instead of ListView in your activity_main.xml?
Change this part of activity_main.xml
<View
android:id="#+id/inflating_view"
android:layout_below="#+id/toggle_button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
by
<ListView
android:id="#+id/category_list_view"
android:layout_below="#+id/toggle_button"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
In your adapter replace
convertView = (View) inflater.inflate(R.layout.activity_category, null);
by
convertView = inflater.inflate(R.layout.activity_category, null);
No need to cast it.
Remove activity_category_list.xml and CategoryListActivity.java.
Initialize & use ListView & Adapter in MainActivity.java
Try this it will surely work.
In this case what you can do is, create a empty layout in your main activity xml. Set a ID for that. While inflating the listview, inflate it to that layout.
In activity_main.xml include a relative layout as follows. Your parent layout is relative_layout. Add another layout like this.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/login_button" > //make sure you use this property to tell where you want to place the view in the screen. This should be below your last button.
</RelativeLayout>
Since login_button is last button in your view, i have recommended,
android:layout_below="#+id/login_button"

Android Custom ListView Rows: Text Style not being applied

Trying to create custom rows in my listview (to look like this). I've created a custom row layout & derived adapter class. The data loads and shows fine, but the text is not using any format/style specified in my custom row .xml layout file. It's all just the default size/weight, etc.
Here's the custom row layout (listview_desc.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:background="#222222">
<TextView
android:id="#+id/name"
android:text="Name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="10dip"
android:textStyle="bold"
android:textSize="20dip"
/>
<TextView
android:id="#+id/description"
android:text="Description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="10dip"
android:textSize="13dip" />
</LinearLayout>
Here's my main layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:theme="#android:style/Theme.NoTitleBar"
android:minWidth="25px"
android:minHeight="25px"
android:background="#drawable/gradient_darkbg">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView1" />
</LinearLayout>
My adapter code (I'm using Xamarin, but I don't think that's the problem...)
public class ListViewFormAdapter : BaseAdapter<Form>
{
List<Form> mForms;
Activity context;
public ListViewFormAdapter(Activity context, List<Form> items)
: base()
{
this.context = context;
this.mForms = items;
}
public override long GetItemId(int position)
{
return position;
}
public override Form this[int position]
{
get { return mForms[position]; }
}
public override int Count
{
get { return mForms.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = mForms[position];
View view = convertView;
if (view == null) // no view to re-use, create new
view = context.LayoutInflater.Inflate(Resource.Layout.listview_desc, null);
view.FindViewById<TextView>(Resource.Id.name).Text = item.Name;
view.FindViewById<TextView>(Resource.Id.description).Text = item.Description;
return view;
}
}
And finally the main activity where I load and use the adapter:
public class HomeScreenActivity : Activity
{
List<Form> mForms;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Create your application here
SetContentView (Resource.Layout.Home);
// Load all forms and populate the main menu
mForms = Utils.FormLoader.LoadForms("Forms");
ListView listView = FindViewById<ListView>(Resource.Id.listView1);
listView.Adapter = new ListViewFormAdapter(this, mForms);
}
}
Sorry for all the code, maybe it'll help someone in the future... thanks for any help.
I'm not sure that this is the problem, but you inflating the views incorrectly. it should be
view = inflater.inflate(R.layout.listview_desc, parent, false);
instead of
view = context.LayoutInflater.Inflate(Resource.Layout.listview_desc, null);
using the 3 parameter version of inflate
What styles aren't showing correctly? I'm not sure what you're expecting or what you're seeing from the question. If it is to do with alignment, you should bear in mind that android:layout_alignParentLeft="true" is not valid in a LinearLayout
Thanks for the response guys. Turns out it was some problem with Git/Xamarin. I committed my sources at another machine, came home, synced up and all my formatting in the row layout xml were gone. Who knows... maybe a cached version was being used or something. I actually had to use the code posted on this page to get it to work (since it was lost), so maybe someone can use this as example code. It works.

Trying to make listview items non-clickable

I have listview that I have populated into a alertDialog When the alertDialog displays the user are able to click on these items in the listview and that is when the problem comes in. I do not want the user to be able to click on the items in the listview and I have already tried adding this to my xml layout android:clickable="false" and android:focusable="false" but I am still getting the same results. Can somebody assist me with this issue that having.
Here is my base adapter class:
public class MyAdapter extends BaseAdapter {
final String[] listItemsFirstRow = {"Item1","Item2"};
final String[] listItemSecondRow = {"Item1", "Item2"};
#Override
public int getCount() {
return listItemsFirstRow.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.twolinelistview, null);
}
((TextView)convertView.findViewById(R.id.text1)).setText( listItemsFirstRow[position]);
((TextView)convertView.findViewById(R.id.text2)).setText( listItemSecondRow[position]);
return convertView;
}
}
And here is my xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_vertical"
android:paddingLeft="15dip"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false" />
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false" />
</LinearLayout>
Modify your BaseAdapter to override isEnabled to tell the ListView that the items aren't clickable.
Example:
#Override
public boolean isEnabled(int position) {
return false;
}
Note that the documentation says this will do exactly what you want:
Returns true if the item at the specified position is not a separator. (A separator is a non-selectable, non-clickable item)
Try setting android:clickable="false" and android:longClickable="false" for your ListView in XML, or you can set it before you set the adapter as well. That should be enough to disable it, but if not android:focusable="false" and android:enabled="false" should definitely do it.
If you are just trying to prevent items from being highlighted another option is to change how it displays selected items and ignoring the events. One way that was suggested in an older question is:
android:listSelector="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"

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