I want to make ListView with images. Something like this.
But some of items have text only and don't have images. For those items I want to show text only.
How can I do that?
Each item in a list view is a separate view, which can be created as needed. Simply inflate a view from two separate layouts in GetView method of your adapter class.
Something like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return new MyViewItem(getImage(), getText(), parent);
}
*****
class MyViewItem extends LinearLayout
{
public MyViewItem(ImageClass image, String text, ViewGroup parent) {
super(parent);
View.inflate(parent, image==null?R.layout.layout1:R.layout.layout2, this);
//Now assign correct text and image using this.findViewById() function.
}
}
I leave it to you to define layout1 and layout2 as well as how to handle actual image and text, but this should do the trick.
You could also have 1 view, but just set visiblity to GONE on the image when you dont want the image to be there. As long as you've set up your layout appropriately, the text should pop over to the edge again just fine!
Related
How can I generate the following layout in an Android list view ?
I need the background of a divider to be a gradient stretching across different items. Is this possible?
If you want to achieve this just extend an adapter, like BaseAdapter and do something like this:
int[] drawables = {R.drawable.back_one, R.drawable.back_two, R.drawable.back_three};
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
.....check if view is null otherwise inflate a new layout.....
if(drawables.length < 3) {
//You can assign one of the backgrounds
view.setBackdroundResource(drawables[i]);
}
}
I create ListView and generate its content with BaseAdapter. The ListView contains Button and hidden ImageView for each row. I put OnClickListener on Button to show ImageView.
Scenario:
ListView has 9 rows, and 3 rows visible on screen.
And then I click Button on first row.
Problem:
ImageView on first row shown successfully, but also on fourth and sixth row.
It happens also when I click Button on second row. ImageView on fifth and seventh row is shown.
Question:
Why is that happens? and how to solve it?
This is the code:
UI Thread
.....
adapter = new ContentAdapter(context, content);
listView.setListAdapter(adapter);
.....
ContentAdapter
.....
public View getView(int position, View convertView, ViewGroup parent) {
.....
final ImageView image = (ImageView)convertView.findViewById(R.id.image);
((Button)convertView.findViewById(R.id.button)).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
image.setVisibility(View.VISIBLE);
}
});
.....
}
.....
do you check for the view if null or something
if(view == null)
view = ((Activity)YourActivity.get()).getLayoutInflater().inflate(R.layout.list_item, null);
The ListView handles memory, i.e. it recycles views, it does not create a new view (vonverView in you case) each time, but instead it uses a previously generated view (which is convertView).
So when you scroll you are seeing (for example) row1's view on your newly created row. this is why you see that the image is already shown.
To avoid that you must set your image's visibility to View.INVISIBLE.
public View getView(int position, View convertView, ViewGroup parent) {
.....
final ImageView image = (ImageView)convertView.findViewById(R.id.image);
image.setVisibility(View.INVISIBLE);
((Button)convertView.findViewById(R.id.button)).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
image.setVisibility(View.VISIBLE);
}
});
.....
}
With that, you will not see a visible image when you scroll, ALTHOUGH, if you make row1's image visible, and you scroll down, when you scroll up again you will find row1's image invisible too, in this case you have to save the state of images somewhere (ArrayList for example, or a Map<Integer position, Boolean isvisible>).
With that being said, you also have to check ViewHolder Pattern for adapters, for better memory consumption.
Hope this helps
I have a multiple choice list view and for its adapter I have designed a layout file. I have an image view in the layout and when it's clicked, I want to know what child of the list it is. I mean the child id for the its parent which is the list to further use the method list.getChildAt(???). can anyone tell me how to get that?
The image is independent of the list view and for its onClick attribute I've written a different method that changes image view resource... How can I know which child that a particular imageView is when I click on it?
In the XML layout I have this:
<ImageView
android:id="#+id/choice_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="deleteSelected" />
And here is a part of deleteSelected method:
public void deleteSelected(View view) {
icon = (ImageView)view.findViewById(R.id.choice_image);
list.getChildAt(???); \\ To know which child the view is
}
I have set the adapter as follows:
list.setAdapter(new ArrayAdapter<String>(this, R.layout.list_choice_multiple,
R.id.choice_text, terms) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
icon = (ImageView)v.findViewById(R.id.choice_image);
icon.setImageResource(R.drawable.delete_off);
icon.setTag(R.drawable.delete_off);
return v;
}
});
How can I set the id for each image view so I can access it by getID() method within deleteSelected()?
ListView has a getFirstVisiblePosition method, using that you can calculate the child position based on its position in the list view (which is a parameter passed in to the onItemClicked method of the listener).
int childIndex = listView.getFirstVisiblePosition() - position;
If you're clicking on a child of the row view (View used in the ListView, created by the adapter), then you need to know which position the row belongs too - simplest way is to store the position in the tag of the child when you set the onClickListener
Simple answer: You are writing that the click happens on the ImageView. The ImageView is not associated with the ListView.
So there is no relationship between your click or any element in the ListView.
When clicking on the ImageView, though, the onClick receives a reference to the ListView itself. So what you are trying to achieve? Please be more precise.
Basically first you will have to set an onClickListener for your list-item's ImageView in getView() of the Adaptor.
Now with onClickListener you get the view that is clicked as function parameter to onClick(). Set a different background for this view (ImageView) object.
Hope this is clear. Let me know.
I have a dropdown navigation list in my ActionBar. I'd like to change the background color of the list item background depending on their position, as well as the currently selected item.
I've created my own class that extends ArrayAdapter and changes the background like so:
#Override
public View getView (int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
v.setBackgroundColor(Color.parseColor(VideoGroup.getColorForId(position)));
return v;
}
#Override
public View getDropDownView (int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
v.setBackgroundColor(Color.parseColor(VideoGroup.getColorForId(position)));
return v;
}
This however results in the following – notice that the actual list items look pretty good, but the currently selected one does not.
How can I get the background color for Group 1 here to fill up the navigation button's area as a whole?
Unfortunately, the Spinner itself is an image, so it will be hard to make it change colors because you'll ideally need an image for each color. You won't be able to make the background on the text expand beyond the triangle, for example. It can definitely be done, but it will probably mean customizing things quite a bit.
An alternative (and maybe simpler) way to apply a color mask to a view is to use a filter:
spinner.getBackground().setColorFilter(THE_COLOR_GOES_HERE, PorterDuff.Mode.MULTIPLY);
I am working on customize (inflated) list view. In which I have used the text and background image for text (as per the condition).
Now I am facing problem in scrolling the list view that background of text view is overlapping to the other text views.
Here is the sample code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
TextView Txt1=(TextView)icontextlayout.findViewById(R.id.txt1);
if(disp1==true)
{
Txt1.setBackgroundResource(R.drawable.pic)
}
else
Txt1.setText("Text1 "+strUser);//
TextView Txt2=(TextView)icontextlayout.findViewById(R.id.txt2);
if(disp2==true)
{
Txt2.setBackgroundResource(R.drawable.pic);
}
else Txt2.setText("Text2: "+strIndus);
return icontextlayout;
}
Could you please help me out that background image pic do not overlap the others background.
Thanking you...
The problem is that you must set a default background when you don't need a background. For instance:
if(disp1==true){
Txt1.setBackgroundResource(R.drawable.pic);
Txt1.setText("");
}
else{
Txt1.setText("Text1 "+strUser);//
Txt1.setBackgroundDrawable(null);
}
Also, if you don't mind, I like to give you my opinion about your code:
That's not they way in which list are usually populated. Take a look at this answer: How to load the Listview "smoothly" in android
convertView is used to reuse rows. In your case you are doing something like:
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
Which is bad, because you are not actually using the convertView (when you call inflater.inflate) it will create a new row, thus your list will be really slow.
if(disp2==true) is redundant. You should consider using just: if(disp2).