I have a problem with making negative margin for view of item which belongs to listview.
My items look like this:
I would like to lift second item and third and so on. The final effect should look like this
I tried with setTop method.
private class MyCustomAdapter extends ArrayAdapter<Integer> {
public MyCustomAdapter()
{
super(ListOfBeaconPlaces.this, R.layout.list_of_places_item_view, drawables);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View takenView = convertView;
if (takenView == null)
{
takenView = getLayoutInflater().inflate(R.layout.list_of_places_item_view, null, false);
}
final CuttedImageView cuttedImage = (CuttedImageView) takenView.findViewById(R.id.list_item_view);
cuttedImage.setImageResource(drawables.get(position));
if (cuttedImage.getHeightOfDrawnTransparentTriangle() != 0)
{
cuttedImage.setTop( (int)-cuttedImage.getHeightOfDrawnTransparentTriangle());
}
return takenView;
}
}
CuttedImageView is my custom class which inheriting from ImageView
Height of this triangle is knew after I first draw it on layout, but it's not a problem. I try to play with LayoutParameters, but it's also doesn't work for my.
Is there any posibility to make whole item margin negative?
I saw question, which talk about setting margin for item in linearlayout or relative layout or inside the item of listview, but I can't find nothing aboout changing margin of whole item.
In your xml file, in your listview set the divider height to a negative number to get an overlaping effect.
like this
android:dividerHeight="-10.0dp"
Related
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'm trying to add some extra space between the 4th and 5th items in the listview. What are my options?
I tried doing that in adapter's getView(), as well as manually getting access to the fourth element and adding padding to it.
Is there a better way to do this?
Another way to do this would be to use a different layout for the the 4th item (that has additional padding). It's similar to your solution but maybe a bit "cleaner". I'm assuming that you're extending ArrayAdapter.
In your adapter override the getViewTypeCount() method:
#Override public int getViewTypeCount() {
return 2;
}
This way you're telling your adapter that you will use two different layouts for your items. Next, you have to specify which items will be of which type by overriding another method:
#Override public int getItemViewType(int position) {
if(position == 3) {
return 0;
} else {
return 1;
}
}
This will tell your adapter to use a different view (only) for the 4th element in the list, and it will not be reused for other elements. Now for the last part, override onCreateView():
#Override public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
if(position == 3) {
convertView = inflater.inflate(R.layout.your_layout_with_padding, parent, false);
} else {
convertView = inflater.inflate(R.layout.your_regular_item_padding, parent, false);
}
//TODO this is the place to initialize your view holder
} else {
//TODO this is the place to restore your view holder
}
//TODO setup your view here
return convertView;
}
For the item with position == 3 (4th item in the list) convertView argument of the getView() method will be null, because that is the first (and only) item of the type 1 in the list. Therefore you can inflate a different layout that includes a padding for that item.
I thought to some ways but if i have to be honest the only way to do this well is to change the layout in the adapter when the position is equal to 4. I meant that you can do an xml file with a RelativeLayout of the height that you want as space between the 4th and 5th element and set the visibility to gone and put him above all your adapter's elements. When the position is equal to 4 in your getView you set the visibility of that item to visible with nameOfYourRelativeLayout.setVisibility(View.VISIBLE)
So you can add this blank space only between 4th and 5th element. Mine is just a suggestion but i think it can work well.
Layout all of your items in the listview to include your data as well as a header view, maybe a textview or even a Viewgroup like another layout. Keep the header invisible until some logic in your code triggers (i.e. pos ==4) and make the header visible
Basicaly, my question is similar to this one:
Scrolling a ListView changes everything from White to Black
The only difference is that I'm dealing with a TextView that changes the color upon scrolling (the TextView is inside a ListView).
I looked up if there's a method similar to setCacheColorHint(Color.WHITE) for a TextView - I didn't find it.
Perhaps I should dynamically set the default TextColor? Because currently, it's being set in XML and then changed in code.
How can I handle this?
Code for changing the color to blue:
private void highlightSelectedFile(View vw)
{
TextView fileName = (TextView) vw.findViewById(R.id.file_name);
//Log.v("color: ", Integer.toString(fileName.getCurrentTextColor()));
if(fileName.getCurrentTextColor() == Color.BLACK) {
fileName.setTextColor(Color.BLUE);
} else {
fileName.setTextColor(Color.BLACK);
removeFromSelectedFiles(new File(fileName.getText().toString()));
}
}
These TextView's go back to BLACK after I scroll the ListView they're inside in:
ListView lv = (ListView) ac.findViewById(android.R.id.list);
Only put this statement in your list in XML file. android:scrollingCache="false"
It will solve your problem.
In your adapter you might be using a data item that applies data to your views in Adapter. When you scroll, your Views are recycled and your getView() is called with a different View object. Your problem can easily be fixed. Just add one more int color; variable in you data item and use it like this.
public View getView(int position, View convertView, ViewGroup parent) {
// efficient stuff here
// after applying your data
fileName.setTextColor(data.color);
}
also change this method:
private void highlightSelectedFile(DataItem data) {
if(data.color == Color.BLACK) {
data.color = Color.BLUE;
} else {
data.color = Color.BLACK;
removeFromSelectedFiles(new File(fileName.getText().toString()));
}
// to update ListView
myAdapter.notifyDataSetChanged();
}
I am trying to get have the lower part of list view slide down, by hiding an unhiding linear layout in list_item. The problem is the view seems to get reused in LayoutAdapter so that the change does not just effect the view I intended to apply it to. Instead it shows up wherever the view is reused. How can I restrict the drop down to just the view on which I requested the dropdown? By drop down I mean unhide the linear layout.
There will always be as many Views in the List as can be seen by the user. When the user scrolls, the views that go out of view get reused to show the new list data the user scrolled to. You need to reset the list item's state when they are redrawn.
Add a boolean variable 'expanded' to the object that stores the list data. (The objects you add to the ArrayAdapter). Set expanded = true when the user expands the LinearLayout in the listItem.
public class MyListItem
{
public boolean expanded = false;
// data you are trying to display to the user goes here
// ...
}
Then do this in the list adapter's getView method
public class MyListAdapter extends ArrayAdapter<MyListItem>
{
public MyListAdapter (Context context, ArrayList<AudioPlaylist> objects)
{
super(context, R.layout.list_item, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout rowLayout;
MyListItem item = this.getItem(position);
if (convertView == null)
{
rowLayout = (LinearLayout) LayoutInflater.from(this.getContext()).inflate(R.layout.list_item, parent, false);
}
else
{
rowLayout = (LinearLayout) convertView;
}
//set the textviews, etc that you need to display the data with
//...
LinearLayout expanded = rowLayout.findViewById(R.id.expanded_area_id);
if (item.expanded)
{
//show the expanded area
expanded.setVisibility(View.VISIBLE);
}
else
{
//hide the area
expanded.setVisibility(View.GONE);
}
return rowLayout;
}
}
Make sure your list_item.xml has a LinearLayout wrapping the whole thing otherwise you will get an cast exception.
Hope that helps...
I have a ListView powered by a custom adapter that dynamically changes the background color of each row based on its contents. The getView looks like this:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
Power power = powers.get(position);
if(row == null)
{
row = getLayoutInflater().inflate(android.R.layout.simple_list_item_2, parent, false);
}
TextView text1 = (TextView)row.findViewById(android.R.id.text1);
TextView text2 = (TextView)row.findViewById(android.R.id.text2);
text1.setText(power.name);
text2.setText(power.getAttackLine());
row.setBackgroundColor(0xFF0000FF);
return row;
}
All that works peachy, except that whenever I select an item from the list, the standard red/orange highlight only shows up behind the row, only visible for a few pixels on each side of it. Is there a way to get the selection to show up on top of the background?
Try android:drawSelectorOnTop="true" in the <ListView> element in your layout.
I think the problem is that you're using simple_list_item_2, which has some padding/margin built into it. I recommend making your own version of simple_list_item_2, wherein you have both the height and the width set to fill_parent. You can see the latest simple_list_item_2 here.