Android - ExpandableListView feature not working.. - android

What I'm trying to do is to have a listview item with a button in each list viewitem.
When the Buttton is being pressed I want a layout that is at gone state will be visible and expand with animation down, and if the layout is shown than when the same button is being preesed than the layout will slide up and be gone again.
In order to do so I've created the next layout for the listview item -
<?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="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tilte_info">
<TextView
android:id="#+id/textView_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="15dp"
android:text="TextView"
android:textSize="20sp" />
<Button
android:id="#+id/button_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="25dp"
android:text="Open" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#5C83AF"
android:visibility="gone"
android:id="#+id/extend_info">
<TextView
android:id="#+id/textView_more_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="15dp"
android:text="TextView"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
As you can see there are two layouts - one is tilte_info which is always shown and have the button in it, and the other one is extend_info which will be shown or hide by the button click.
Now I've used the next code in order to try and make it work -
public class MainActivity extends Activity {
ArrayList<Place> placesList = new ArrayList<Place>();
placeAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Place place1 = new Place("Place num 1", "some info on place 1");
Place place2 = new Place("Place num 2", "some info on place 2");
Place place3 = new Place("Place num 3", "some info on place 3");
placesList.add(place1);
placesList.add(place2);
placesList.add(place3);
ListView lv = (ListView) findViewById(R.id.listview_1);
adapter = new placeAdapter(this);
lv.setAdapter(adapter);
}
class placeAdapter extends ArrayAdapter<Place> implements OnClickListener{
public placeAdapter(Context context) {
super(context, -1, placesList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null){
// use the LayoutInflater to inflate an XML layout file:
convertView=getLayoutInflater().inflate(R.layout.list_item, parent,false);
}
TextView textTitle = (TextView) convertView.findViewById(R.id.textView_title);
TextView textInfo = (TextView) convertView.findViewById(R.id.textView_more_info);
Button open = (Button) convertView.findViewById(R.id.button_open);
infoLayout = (View) convertView.findViewById(R.id.extend_info);
infoLayout.setVisibility(View.GONE);
open.setOnClickListener(this);
Place place = placesList.get(position);
textTitle.setText(place.getTitle());
textInfo.setText(place.getInfo());
return convertView;
}
#Override
public void onClick(View v) {
if(infoLayout.isShown()){
slide_up(MainActivity.this, infoLayout);
infoLayout.setVisibility(View.GONE);
}else{
infoLayout.setVisibility(View.VISIBLE);
slide_down(MainActivity.this, infoLayout);
}
}
}
public static void slide_down(Context ctx, View v){
Animation a = AnimationUtils.loadAnimation(ctx, R.anim.slide_down);
if(a != null){
a.reset();
if(v != null){
v.clearAnimation();
v.startAnimation(a);
}
}
}
public static void slide_up(Context ctx, View v){
Animation a = AnimationUtils.loadAnimation(ctx, R.anim.slide_up);
if(a != null){
a.reset();
if(v != null){
v.clearAnimation();
v.startAnimation(a);
}
}
}
}
The thing is that I tried to debug the code and it getting into the onclick function but nothing is happening - the layout that is gone not been shown.
I've chacked the animation code with simple textview outside the listview and it worked, but when im trying to use it in the listview item, it doesn't work.
Any ideas why?
Thanks for any kind of help

Use ExpandableListView. You have to extend the BaseExpandableListAdapter to your adapter and override methods. In this methods, override getGroupView to display the name of expandablegroup and override getChildView method to inflate the child view for list. After inflating the layout for child, set whatever animation you want on that view.

you shoud use expandableview for it...
basic example fot that is here... expandavlelistview example

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"

How to setVisibility in a listview by a button outside it?

I have a custom Listview with 1 Button on a row
I would like to add a button outside the Listview to set the visibility on button on all rows
How can i achieve this?
And i DONT wanna use notifyDataSetChanged that reload all data
Anyone got an idea of this??
<?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:id="#+id/notice_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="16dp" />
<TextView
android:id="#+id/notice_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/notice_title"
android:textSize="8dp" />
<ImageButton
android:id="#+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_delete"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:visibility="invisible" />
</RelativeLayout>
Adapter_notice.java
public class Adapter_notice extends ArrayAdapter<notice> {
private Context context;
private int listRow;
private notice[] notice;
public List<String> listTag = new ArrayList<String> ();
public Adapter_notice(Context context, int listRow, notice[] Rows) {
super(context, listRow, Rows);
this.listRow = listRow;
this.context = context;
this.notice = Rows;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
//Log.d("edittext", "items !empty="+listTag.contains(listTag.get(position)));
LayoutInflater inflater = LayoutInflater.from(context);
row = inflater.inflate(listRow,parent, false);
notice row_notice = notice[position];
TextView tv1 = (TextView) row.findViewById(R.id.notice_title);
tv1.setText(row_notice.gettitle());
TextView tv2 = (TextView) row.findViewById(R.id.notice_date);
tv2.setText("Date:"+row_notice.getdate());
ImageButton btn = (ImageButton) row.findViewById(R.id.btn_delete);
return row;
}
}
I have a custom Listview with 1 button on a row I would like to add a
button outside the Listview to set the visibility on button on all
rows How can i achieve this?
And i DONT wanna use notifyDataSetChanged that reload all data Anyone
got an idea of this??
Create layout that contains ListView and Button. ListView has set height to WRAP_CONTENT.
Then create onClickListener for Button and onClick() hide your ListView:
btn.setOnClickListener(new View.OnClickListener {
public void onClick(View v) {
if (listView.getVisibility() == ListView.VISIBLE) {
listView.setVisibility(ListView.INVISIBLE);
}
else {
listView.setVisibility(ListView.VISIBLE);
}
}
});
Note: Difference between INVISIBLE and GONE is that GONE property doesn't take place in layout.
in onClick() of the button outside the list, do something like
listview.setAdapter(changedAdapter)
Where changedAdapter will be a new set of adapter OR
adapter.setButtonVisibility(false);
listview.setAdapter(adapter).
Create a new method in your Adapter class which sets a boolean value based on which the getView will return view (if boolean is true, Button field will be made invisible)
public void setButtonVisibility(boolean hideButton){
this.hideButton = hideButton;
}
getView(){
...
if(hideButton){
//hide button
}
}
Use
ListView.setVisibility(View.GONE / View.VISIBLE / View.INVISIBLE);
Since you want to temporarily disable the visibility use View.INVISIBLE and View.VISIBLE
In your OnClickListener() of the decider button ,set the Adapter again for the list .
and keep a public Boolean variable outside the List to decide visibility of the specific button, by validating Boolean variable.
on button click event add
yourListView.setVisiblity(View.INVISIBLE);
to hide the list view

How to I do a loop of a widget(imageview and textview) in android?

Does anyone know how I could create a for loop(?) for my imageView and textView without adding them in my XML file? I'm not sure if it is possible too..so I would appreciate if someone could help me in this.
For your info, I would like to grab data from another activity. eg. If the user click the add to Favourite button, I would display another imageView & textView in this activity of the clothes image and name. The activity will also display the previous items that is added to the page.
XML file:
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/name"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="a" />
</LinearLayout>
Inside my onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_favourite);
editButton = (Button)findViewById(R.id.edit);
image = (ImageView)findViewById(R.id.image);
name = (TextView)findViewById(R.id.name);
}
Thank you.
I think what you are going to want to do is in your layout have a ListView, and then you create something that implements ListAdapter (ArrayAdapter is a good choice). In your adapter you can reuse one xml file that would contain your ImageView and TextView.
There are a lot of good tutorials out there on it, Googling "ListView Adapter" will get you pretty far. Here's a good one: http://www.vogella.com/articles/AndroidListView/article.html
Yours is a pretty simple case, so you can use an ArrayAdapter like this:
Activity:
public class MainActivity extends Activity {
private ArrayAdapter<String> listAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>()) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (convertView == null)
{
v = super.getView(position, convertView, parent);
}
String text = getItem(position);
TextView textview = ((TextView) v.findViewById(android.R.id.text1));
textview.setText(text);
// Now you can set an image by calling
// textview.setCompoundDrawablesWithIntrinsicBounds(...);
return v;
}
};
((ListView) findViewById(R.id.listView)).setAdapter(listAdapter);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
private int i = 0;
#Override
public void onClick(View view) {
listAdapter.add("item number: " + (++i));
listAdapter.notifyDataSetChanged();
}
});
}
}
Layout activity_main:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
tools:listitem="#layout/listview_row"
android:layout_above="#+id/button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Alternative:
If you are bent on not using a ListView or for whatever reason you can't use a list view, you can always inflate a layout and add it to another layout in your app. The code below would then replace the code above in the button's on click:
View row = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null); /* null here means it's not attaching/populating a view you already have */
((TextView) row.findViewById(android.R.id.text1)).setText("item number: " + (++i));
((ViewGroup) findViewById(R.id.linearlayout)).addView(row);
findViewById(R.id.linearlayout).invalidate();
Using a ListView here is the right way to go, so this is kind of a last resort.
I'm not sure of what you want, maybe this?
for (int i = 1; i <= 20; i++) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button btn = new Button(this);
btn.setId(i);
final int id_ = btn.getId();
btn.setText("button " + id_);
btn.setBackgroundColor(Color.rgb(70, 80, 90));
linear.addView(btn, params);
btn1 = ((Button) findViewById(id_));
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(view.getContext(),
"Button clicked index = " + id_, Toast.LENGTH_SHORT)
.show();
}
});
}

Android: button showing up multiple times in list view

I trying to write code to highlight the selected value of the list with "Next" button at the bottom of the layout. But for some reason, after every list item, "next" button also shows up. Can someone please help me resolve this problem?
Here is the layout file:
<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:id="#+id/questionLayout"
>
<TextView android:id="#+id/txtExample"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#000000"
android:background="#FF0000"
/>
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id = "#+id/next"
android:text="Next"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_gravity="center"
android:layout_weight="50"
/>
<Button
android:id = "#+id/submit"
android:text="Submit"
android:layout_width = "0dp"
android:layout_height = "wrap_content"
android:layout_weight="50"
android:layout_gravity="center"
/>
</LinearLayout>
</LinearLayout>
Java Code:
public class updateList extends Activity {
private SelectedAdapter selectedAdapter;
private ArrayList<String> list;
int correct_answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<String>();
list.add("Choice One");
list.add("Choice Two");
list.add("Choice Three");
selectedAdapter = new SelectedAdapter(this,0,list);
selectedAdapter.setNotifyOnChange(true);
ListView listview = (ListView) findViewById(R.id.listExample);
listview.setAdapter(selectedAdapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
// user clicked a list item, make it "selected"
selectedAdapter.setSelectedPosition(position);
}
});
}
}
Thanks in advance
SSP
Selected Adaptor class:
public class SelectedAdapter extends ArrayAdapter{
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
public SelectedAdapter(Context context, int textViewResourceId,
List objects) {
super(context, textViewResourceId, objects);
}
public void setSelectedPosition(int pos){
selectedPos = pos;
// inform the view of this change
notifyDataSetChanged();
}
public int getSelectedPosition(){
return selectedPos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// only inflate the view if it's null
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.activity_main, null);
}
// get text view
TextView label = (TextView)v.findViewById(R.id.txtExample);
// change the row color based on selected state
if(selectedPos == position){
label.setBackgroundColor(Color.CYAN);
}else{
label.setBackgroundColor(Color.WHITE);
}
label.setText(this.getItem(position).toString());
/*
// to use something other than .toString()
MyClass myobj = (MyClass)this.getItem(position);
label.setText(myobj.myReturnsString());
*/
return(v);
}
}
change your listview in xml as like this
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"//===== set maximum heighthere
android:layout_marginBottom="50dp"// === give some space at bottom so that buttons will appear
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
But for some reason, after every list item, "next" button also shows up.
The ListView's row layout is determined by the layout you inflate in getView() or pass to your Adapter's super class if you haven't overridden getView(). Double check this layout and remove the unwanted code.
Addition
The layout for your ListView's items only needs to be one TextView since you only want to display a phrase in each. However you are currently passing your entire main layout, this creates the Buttons, an unused ListView, and everthing else in every row...
Instead use android.R.layout.simple_list_item_1 in getView(), of course you'll need to change the id you pass to findViewById() as well:
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(android.R.layout.simple_list_item_1, null);
}
// get text view
TextView label = (TextView)v.findViewById(android.R.id.text1);
Please watch Android's Romain Guy discuss writing an efficient adapter to speed things up.

Categories

Resources