default padding or margin for listview - android

Is there some sort of built-in default margin or padding for a ListView?
I have a simple LinearLayout with an ImageView and a ListView.
The entire ListView appears to have a slight margin or padding.
<?xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#drawable/starbuzz_logo"
android:contentDescription="#string/starbuzz_logo"/>
<ListView
android:id="#+id/listView_drinks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/drinks" />
The screenshot is attached. I am not allowed to embed an image. screenshot

The padding or margin probably comes from the default layout for each list item. To get rid or change the size of the padding or margin, create a custom layout for the list items.
item_list_coffee.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
then override getView() in your adapter so that it uses your custom layout
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list_coffee, parent, false);
}
final String string = getItem(position);
// find textview and set text to string
return convertView;
}

Related

How do I add margin values to inflated ListView?

This is my code for how each row looks.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="120dp"
android:id="#+id/recipe_container"
android:layout_margin="12dp"
android:background="#f1f1f1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/recipe_name_text_view"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:textSize="32sp"
android:text="DUMMY TEXT"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="#+id/recipe_time_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DUMMY TEXT"/>
<TextView
android:id="#+id/recipe_difficulty_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DUMMY TEXT"/>
</LinearLayout>
</LinearLayout>
<ImageView
android:id="#+id/recipe_thumbnail_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sladice"/>
</LinearLayout>
As you can see I have margin set, if I check preview it is also shown.
I populated with inflate this listivew.
This is activity_sladice.xml.
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/recipe_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.recepti.Sladice"
android:background="#color/colorPrimary">
</ListView>
Now each row is together, there is no spacing between left, right, bottom , top.
If I add margin or padding to listview it only works on the entire list, not on each row.
How to do it? I know I can add divider between each row but I also want spacing right and left.
This is getView method from custom adapter.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View recipeView = convertView;
ReceptThumbnail recipe = getItem(position);
// Inflate view if to be inflated
if (recipeView == null) {
recipeView = LayoutInflater.from(getContext()).inflate(R.layout.recipe_item, parent, false);
}
TextView recipeName = (TextView) recipeView.findViewById(R.id.recipe_name_text_view);
recipeName.setText(recipe.getName());
TextView recipeTime = (TextView) recipeView.findViewById(R.id.recipe_time_text_view);
recipeTime.setText(recipe.getTime());
TextView recipeDifficulty = (TextView) recipeView.findViewById(R.id.recipe_difficulty_text_view);
recipeDifficulty.setText(recipe.getDifficulty());
ImageView recipeImage = (ImageView) recipeView.findViewById(R.id.recipe_thumbnail_image_view);
recipeImage.setImageResource(recipe.getImageResourceID());
}
If you want to add margins to the ListView, add margns to the listview.
If you want to add margins to the items, add margins to the items.
It is simple.
However, I suggest you to use ConstraintLAyout. And RecyclerView instead of ListView.
Try using padding in the LinearLayout, and create another LinearLayout as a child of the original, and move the background attribute to it.
try setting margin programmatically in getView method using below method.
public static void setMarginLeft(View v, int left) {
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams)v.getLayoutParams();
params.setMargins(left, params.topMargin,
params.rightMargin, params.bottomMargin);
}

TextView overlaps ImageView inside a CardView

I'm trying to do a ListView of CardViews.
The CardView contains an ImageView at the top and several TextViews at the bottom.
I manage to do everything right, although for some reason the image don't fit the CardView (so it gets cropped at the top of it) and the TextViews overlaps the rest of the image.
I tried a lot of different solutions, although nothing worked for me and i cam't figure out why.
The main layout:
<ListView android:id="#+id/item_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
The CardView layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin">
<android.support.v7.widget.CardView android:id="#+id/item_card"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/item_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/item_image_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:id="#+id/item_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
And the getView() methid:
public View getView(int position, View convertView, ViewGroup parent) {
View cardView;
if (convertView == null) {
LayoutInflater inflater = ((Activity) this.getContext()).getLayoutInflater();
cardView = inflater.inflate(R.layout.item_card_list, parent, false);
}
else {
cardView = convertView;
}
ImageView itemImage = (ImageView)cardView.findViewById(R.id.item_image);
TextView itemTitle = (TextView)cardView.findViewById(R.id.item_title);
TextView imgDesc = (TextView)cardView.findViewById(R.id.item_image_desc);
TextView itemDesc = (TextView)cardView.findViewById(R.id.item_desc);
Item currItem = this.getItem(position);
itemImage.setImageDrawable(currItem.mImageDrawable);
itemTitle.setText(currItem.mTitle);
imgDesc.setText(currItem.mDescription.imageDesc);
itemDesc.setText(currItem.mDescription.descText);
itemImage.setScaleX((float)1000 / currItem.mImageDrawable.getMinimumWidth());
itemImage.setScaleY((float)1000 / currItem.mImageDrawable.getMinimumWidth());
return (cardView);
}
It seems like the CardViews have a max height or something..can't tell :(
Thanks in advance!
My approach was all wrong. I realized that the setScale() methods I used only scaled the bitmap, and not the ImageView itself. Although when I tried to resize the ImageView before it was even layed down on the canvas, I got no luck either. So I did this:
Instead of trying to resizing the ImageView after I assigned it with a small bitmap, I resized the bitmap itself before setting it to the ImageView. Fixed everything :)

TextView in ListView not selectable on entire row

My XMLs are
activity_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp" >
<ListView
android:id="#+id/categoriesList"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
And the customAdaptor
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp" >
<TextView
android:id="#+id/categoryIDText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible">
</TextView>
<TextView
android:id="#+id/categoryName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20px" >
</TextView>
</LinearLayout>
So, within each row, I have two textViews. One is hidden, and other is visible.
Now, when I click on any row, the only clickable area is the one where TextView's string ends.
i.e. if my TextView categoryName has one element set as Hello then the listview's row looks like
Hello [BLANK SPACE HERE]
And when i touch the are where it is BLANK SPACE, it does not respond to the touch. But when I touch the area, where it is Hello, then it responds.
What should I do to make the entire row clickable?
Thanks
EDIT
listView.setAdapter(new CategoryAdapter(this, categories));
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
}
And my custom adaptor
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_view_category, parent, false);
TextView textViewID = (TextView) rowView.findViewById(R.id.categoryIDText);
TextView textViewName = (TextView) rowView.findViewById(R.id.categoryName);
textViewID.setText(""+data.get(position).getId());
textViewName.setText(data.get(position).getName());
return rowView;
}
Apparently I had to change the android:layout_width root element of my activity.xml file.
That did the trick for me.
The root element of your listview item has android:layout_width="wrap_content" change it to match_parent (in your customAdaptor xml)
Add android:clickable="false" to the TextView. This will make the touch event fall through to your underlying row.
Have you tried setting the visibility to "gone"?
<TextView
android:id="#+id/categoryIDText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone">
</TextView>

How to show Text on Image

I have written a code, in which i am showing images in GridView, but now i want to show text in bottom of every image.
And i want to show my Grid like this:
but getting like this [also want to show Text for Image]:
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:numColumns="2"
/>
</FrameLayout>
You need to define a custom grid item layout which contains a textview to assign the text.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/thumbnail"
android:padding="8dp"
android:scaleType="cropCenter"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="bottom"
android:textColor="#android:color/white"
android:background="#55000000" />
</FrameLayout>
Here we have created a FrameLayout which has the imageview set to match the parent's dimensions, this will be the imageview that displays the photo. Next, there is a TextView which will be used to display the item title and that is aligned to the bottom of the FrameLayout.
Next, we need to edit your adapter to use this grid item layout and render the correct information.
public View getView(int position, View convertView, ViewGroup parent) {
// Inflate the single grid item layout
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.grid_item, parent, false);
}
// Set Image
ImageView thumbnail = convertView.findViewById(R.id.thumbnail);
if (thumbnail != null) {
thumbnail.setImageResource(mThumbIds[position]);
}
// Set Text
TextView title = convertView.findViewById(R.id.title);
if (title != null) {
title.setText("Image Number: " + position);
}
return convertView;
}
mLayoutInflater should be globally defined in your constructor using
mLayoutInflater = LayoutInflater.from(context);

ExpandableListView - How to set divider only between parent elements

I want to put divider only between parent elements. When i set
android:divider="#drawable/divider" android creates divider between parent elements, but creates divider between child elements too. When i add android:childDivider="#color/transparent" android removes the divider between child elements, but the free space between them remains. Why?
I have tried to android:dividerHeight="0dp" but nothing happened.
At all i want to set divider between parent elements, but i do not want any divider or empty space between child elements.
any ideas how to do that??
In order to remove dividers just from the child views and not between the parents in the expandable list:
add android:childDivider="#00000000" in the ExapandableListView attributes in XML:
<ExpandableListView
android:id="#+id/elv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:childDivider="#00000000" />
Refer this page for more information
Give Divider color and its height (dividers will be visible when groups are collapsed)
<ExpandableListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/color_black"
android:dividerHeight="1dp"
android:groupIndicator="#null" />
The trick is to create an extra view for collapse group layout and last child layout.
collapse_group.xml:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"/>
<!-- this is the extra view-->
<View
android:layout_width="fill_parent"
android:layout_height="10dp"
android:background="#android:color/transparent"/>
</LinearLayout>
expanded_group.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"/>
<!-- no extra view-->
</LinearLayout>
And apply the same technique to the child view, for the last child view insert the extra view
What I did was to set the ExpandableListView's divider to 0 and then insert "divider" groups into it's ExpandableListAdapter:
// To get dividers between the groups we add 'divider views' as if they were
// themselves groups.
public int getGroupCount() {
// Actual groups are at even groupPositions, dividers at odd
return (this.data.size() * 2) - 1;
}
public long getGroupId(int groupPosition) {
if(groupPosition % 2 != 0) return R.id.divider;
else return R.id.group;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if(groupPosition % 2 != 0) {
View divider = convertView;
if(divider == null || divider.getId() != R.id.divider) {
divider = this.inflater.inflate(R.layout.divider, null);
}
return divider;
}
View group = convertView;
if(group == null || group.getId() != R.id.group) {
group = this.inflater.inflate(R.layout.group, null);
}
return group;
}
expListView.setDividerHeight(10);
expListView.setChildDivider(getResources().getDrawable(
android.R.color.white));
If you want to remove child divider only, One simple trick is You can create a drawable with same color as of your child item's background color. Then set it as child divider.
ShapeDrawable sd1 = new ShapeDrawable(new RectShape());
sd1.getPaint().setColor(YOUR CHILD ITEM BACKGROUND COLOR);
mExpListView.setChildDivider(sd1);
Or using xml:
android:childDivider="#color/child_bg_color"
If you want to have divider between parent element of the ExpandableListView (Header) and don't want to have divider between children and parent , which is obviously the most natural case, then you have to do following:
In your parent xml file add one View at the bottom of the layout with divider height and divider color that you need.
Example:
Do same in the child xml file. Add one View at the bottom of the layout with divider height and divider color that you need. Make sure divider color and height are same like in parent xml.
Into your ExpandableListView Adapter method
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent)
manage the state of the View divider like this:
Example:
if(isExpanded){
headerDividerView.setBackgroundColor(ContextCompat.getColor(context,R.color.darker_grey));
}else{
headerDividerView.setBackgroundColor(ContextCompat.getColor(context,android.R.color.transparent));
}
BTW : In my case R.color.darker_grey is background color of the parent
Remove from your ExpandableListView xml all dividers and dividers height. Make ExpandableListView to not have dividers and divider height.
You can use attrs like this :
android:groupIndicator="#null"
android:childIndicator="#null"
android:divider="#null"
android:dividerHeight="0dp"
I solved it by adding two views one to header and other to child item like shown below.
Header.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="wrap_content">
<RelativeLayout
android:id="#+id/rl_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/square_box"
android:padding="#dimen/padding_10">
<ImageView
android:id="#+id/expandableIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_downarrow" />
</RelativeLayout>
<View
android:id="#+id/view_hidden"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_below="#+id/rl_header"
android:background="#android:color/transparent" />
</RelativeLayout>
child.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="wrap_content">
<RelativeLayout
android:id="#+id/rl_childView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/square_box"
android:padding="#dimen/padding_10">
<TextView
android:id="#+id/tv_startDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:gravity="left"
android:paddingTop="#dimen/padding_5"
android:paddingBottom="#dimen/padding_5"
android:text="Start Date \nSep. 23, 2019"
android:textSize="#dimen/text_16" />
<ImageView
android:id="#+id/iv_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/right_arrow" />
</RelativeLayout>
<View
android:id="#+id/view_hidden"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_below="#+id/rl_childView"
android:background="#android:color/transparent" />
</RelativeLayout>
Now add this code to your Adapter class. The idea is to show/hide the View when group is expanded/collapsed, show on child last item.
#Override
public View getGroupView(int listPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
String listCount = "(" + getChildrenCount(listPosition) + ")";
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater)
this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_header, null);
}
View view_hidden = convertView.findViewById(R.id.view_hidden);
if (isExpanded) {
view_hidden.setVisibility(View.GONE);
} else {
view_hidden.setVisibility(View.VISIBLE);
}
return convertView;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final Medication medication = (Medication) getChild(listPosition,
expandedListPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater)
this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_item, null);
}
View view_hidden = convertView.findViewById(R.id.view_hidden);
if (isLastChild) {
view_hidden.setVisibility(View.VISIBLE);
} else {
view_hidden.setVisibility(View.GONE);
}
return convertView;
}
set like this android:divider="#null" no divider for parents android:divider="2dp" set divider for parents
<ExpandableListView
android:id="#+id/expandable_list"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:divider="2dp"
android:groupIndicator="#drawable/group_indicator" />

Categories

Resources