I have a ViewGroup in top of Activity, 3 buttons and 3 ListView ( they are placed horizontally ). When I scroll ListView from down to up, my buttons and ViewGroup should be scrolled accordingly, from down to up.
My question - how can I implement it? ( scrolling ViewGroup and buttons )
Updated: buttons scrolls ListViews left to right and right to left ( like tab bar ), but ViewGroup and button doesn't moves;
ListView has very convenient method addHeaderView. So put your ViewGroup and buttons into separate xml layout. Inflate view from this xml and add it to your ListView using addHeaderView.
From the top of my head:
1)Make a list adapter for the list view. This class must extend SimpleAdapter, BaseAdapter, etc.
2)Make a XML layout for the list`s item, that includes the buttons and other elements you may desire. (your_item_layout.xml). This layout implements a listview if you want.
3)The list adapter needs an data structure to storage information for the list view, like an ArrayList, Map, Array, etc.
For example: private ArrayList al;
4)This list adapter function
public View getView(int position, View v, ViewGroup vg){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.your_item_layout,null);
/*set as you wish the elements of the item layout*/
Button b1 = v.findViewById(R.id.button1_item_layout);
b1.setText("OPEN FILE " + al.get(position));
b1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
/*do something*/
}
});
}
I hope that helps!
Related
As a little eperiment, I'm trying to do the following.
I have an AXML describing a vertical linear layout which contains a listview (only filling 200dp of the vertical linear layout ). The AXML is inflated when the activity starts with SetContentView. Then the listview is correctly populated with values using its Adapter.
In the GetView method of the listview Adapter, I am trying to also dynamically create a button and add it to the linear layout, but for some reason the button is not added.
If I try to add the button in the constructor method of the Adapter instead, it is correctly added.
Can you tell me what could be possibly going wrong?
Let me add some code:
class TracksAdapter : BaseAdapter<string> {
Activity context;
List<Dictionary<string,string>> trackList;
// constructor
public TracksAdapter (Activity context, List<Dictionary<string,string>> trackList) {
this.context = context;
this.trackList = trackList;
// Just as a little test, if I create the button from here it will be correctly added to linear layout:
var ll = context.FindViewById<LinearLayout>(Resource.Id.linLayForResultsActivity);
Button b1 = new Button(context);
b1.Text = "Btn";
ll.AddView(b1);
}
public override View GetView(int position, View oldView, ViewGroup parent) {
// if I create the button from here it will not be added to the layout
var ll = context.FindViewById<LinearLayout>(Resource.Id.linLayForResultsActivity);
Button b1 = new Button(context);
b1.Text = "Btn";
ll.AddView(b1);
// this other code is working
View view = context.LayoutInflater.Inflate(Resource.Layout.ResultItem, null);
var artistLabel = view.FindViewById<TextView>(Resource.Id.resultArtistNameTextView);
artistLabel.Text = trackList[position]["trackArtistName"];
return view;
}
}
Update: adding some more context information because I know this can be a bit weird to understand without it:
In GetView, I don't need to return the new button I am trying to create there. GetView only need to return a listview view item, but, along its execution, GetView also has to create and add a button to the linear layout containing the listview.
The real code is much more complex than that. I have simplified it in the question. In the real code, the listview items are made of text and a button. The GetView also attaches event handlers to the buttons. Then what I need is, when a user clicks a button in any of the listview items, another button is added below the listview. So I need the code for adding another button to be in GetView, and the button needs to be added outside of the listview, ie. to the linear layout containing the listview.
Use the LayoutInflator to create a view based on your layout template, and then inject it into the view where you need it.
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);
// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");
// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
I looked in you code, you are returning view, while you add the button to ll, you should return ll
what you return in getView() is what you see in the list item layout, since you're adding the button to ll and returning view, the button won't appear.
you can add the button to view as you implementation
Also check this:
Try using boolean addViewInLayout (View child, int index, ViewGroup.LayoutParams params)
http://developer.android.com/reference/android/view/ViewGroup.html#addViewInLayout(android.view.View, int, android.view.ViewGroup.LayoutParams)
It's working... Without making any changes now it's working as it should... ! Ugh!
I really don't know what I was doing wrong here... probably it was because of some sort of caching of older version of the installed APK.. ? I know this sort of stuff can happen, and that's why I've always been uninstalling the app before deplyoing the new version to the device... but still...!
In android, is it possible to get all items inside the list view. Lets say the list view has multiple rows and only 2 rows are visible on the screen while the rest are accessible using the scroll bar. Each row has a radio button and a text view. Is there a way to get all textview of the rows whose radio button is selected and not just the ones visible on the screen.
Your answer may be:
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
You can use custom list view to show your list items with checkbox & textview.
I happened to have a similar requirement where I had multiple EditText inside a ListView and only few of them were visible on the screen. I needed to get the values of all EditText and not just the ones visible on the screen.
Well if you are using a default Adapter, then the way it will work is it will recycle the old views to create new ones. So there is no way to preserve values of those Views which are not visible.
So the only workaround is to create your own Adapter, maybe something like the following, which will not recycle any views, but every time inflate new ones.
public class ListViewAdapter extends ArrayAdapter {
public ListViewAdapter(Context context, ArrayList<Object> items) {
super(context, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return LayoutInflater.from(getContext()).inflate(R.layout.your_layout_for_list_view_item, parent, false);
}
}
After that, as in above answer Lãng Tử Bị Điên has mentioned, you can check in your java code, if your radio buttons are checked or not, and according to that, selected desired TextViews
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
Hopefully this should do it.. It sure worked in my case!
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 custom list view with simple text and button, this button open a dialog that allow user to delete or save a file, but i want to get the view of the row when i push this button to perform a delete animation.
How can i get the view of this specific row, inside on a button click listener?
I use a custom array Adapter with Base Adapter!
extends BaseAdapter implements View.OnClickListener{
Thanks in advance, i don't know if it's necessary to put here the code, it's so long.
you should use the custom adapter for your list view and add tag to your button that represent the position of your row and after that in your clicklistener you should get the tag and find out that which row has been clicked .
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Button yourbtn= (Button) v.findViewById(R.id.yourbtnid);
yourbtn.setTag(position);
yourbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Button btn = (Button)arg0;
int position = Integer.parseInt(btn .getTag().toString());
}
}
You need to do this from the ListView by using ListView.setOnItemSelectedListener(). The OnItemSelectedListener returns the View.
If you're implementing your click action inside the Adapter code itself (which I think is not the best way to do it), you can get an instance of the whole strip by calling getParentView() as many times as needed, depending on how deep into your parent layout the button is.
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!