This is the row of my custom listview. As you can see, there are three imageViews. How should I override the
public View getView(int position, View convertView, ViewGroup parent)
of my adapter class, such that, I can set imageView.setImageResource, no matter how many imageviews I have in my list. Any help is much appreciated.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:id="#+id/LinearLayout01"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="10px" />
<ImageView
android:id="#+id/image1"
android:layout_toRightOf= "#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10px" />
<ImageView
android:id="#+id/image2"
android:layout_toRightOf= "#+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10px" />
</RelativeLayout>
</LinearLayout>
Take on holder class inside your adapter
// View Holder for fast accessing List Row
private class ViewHolder {
public ImageView image;
public ImageView image1;
public ImageView image2;
}
And getView method
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_layout,null);
holder.image = (ImageView)convertView.findViewById(R.id.image);
holder.image1 = (ImageView)convertView.findViewById(R.id.image1);
holder.image2 = (ImageView)convertView.findViewById(R.id.image2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Setting Image Resource here
holder.image.setImageResource(R.drawable.icon);
holder.image1.setImageResource(R.drawable.icon);
holder.image2.setImageResource(R.drawable.icon);
// return the listview row
return convertView;
}
In the ListView row layout why you take LinearLayout and then RelativeLayout inside it, Just take RelativeLayout as a root node.
Related
I have to implement Horizontal scroll view for Child elements of ExpandableListView, now the child elements are shown in Vertical orientation.
<ExpandableListView android:id="#+id/myGroupListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:divider="#color/navDrawerIcon"
android:dividerHeight="1dp" />
item_group.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/userImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:src="#drawable/ic_account_circle_808088_36dp"
android:paddingTop="5dp"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="20dp" />
<TextView
android:id="#+id/groupMemberList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Group Member"
android:gravity="left"
android:paddingTop="15dp"
android:paddingBottom="10dp"
android:paddingLeft="50dp"
android:paddingRight="20dp"
android:textColor="#color/primary" />
</RelativeLayout>
item_group_child.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/sharedCardImage"
android:layout_width="#dimen/image_card_xsmall_width"
android:layout_height="#dimen/image_card_xsmall_height"/>
<TextView
android:id="#+id/sharedBalAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/sharedCardImage"
android:text="TextView"
android:textSize="#dimen/text_size_small"
android:textColor="#color/primary"
android:textAlignment="center"
android:gravity="center" />
</LinearLayout>
I tried to change the item_group_child.xml LinearLayout orientation into horizontal, but no luck.
item_group.xml should be displayed in vertical way, it works, item_group_child.xml should be horizontal way, so the user can scroll child items horizontally. Is there any way to achieve this?
Not with a stock ExpandableListView. ExpandableListView is just a regular vertical ListView where the ExpandableListAdapter handles adding/removing the list items based on the group expand/collapse events.
If you want horizontally scrolling children, then you need to set up your ExpandableListAdapter so that each group has just one possible child view, and when that child view is created, it has a horizontal scrolling view that will contain all the group's children.
Yes, You can achieve this with CustomHorizontalListView. see this link. Just Implement it on your getChildView(). I am just customize my horizontalListView from above link. see following code:
This is your group_child_item.xml
<com.customlayout.HorizontalListView
android:id="#+id/horizontalListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/gray_d7"
android:padding="20dp"
xmlns:android="http://schemas.android.com/apk/res/android">
</com.customlayout.HorizontalListView>
Now inflate above xml into your getChildView():
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastchild, View convertView, ViewGroup parent)
{
ChildHolder childHolder = null;
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_child_item, null, false);
childHolder = new ChildHolder();
childHolder.horizontalListView = (HorizontalListView) convertView.findViewById(R.id.horizontalListView);
convertView.setTag(childHolder);
}
else
{
childHolder = (ChildHolder) convertView.getTag();
}
HorizontalListViewAdapter horizontalListAdapter = new ModuleRoomHorizontalListAdapter(context, groupList, groupPosition);
ChildHolder.horizontalListView.setAdapter(horizontalListAdapter);
return convertView;
}
private static class ChildHolder
{
HorizontalListView horizontalListView;
}
Now implement your item_group_child.xml file for horizontalListViewChild and inflate in getView of HorizontalListAdapter
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/sharedCardImage"
android:layout_width="#dimen/image_card_xsmall_width"
android:layout_height="#dimen/image_card_xsmall_height"/>
<TextView
android:id="#+id/sharedBalAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/sharedCardImage"
android:text="TextView"
android:textSize="#dimen/text_size_small"
android:textColor="#color/primary"
android:textAlignment="center"
android:gravity="center" />
</LinearLayout>
HorizontalListAdapter:
public class HorizontalListAdapter extends BaseAdapter
{
private Context mContext;
private ArrayList<Groups> mGroupListList;
private int mGroupPosition;
public HorizontalListAdapter(Context context, ArrayList<Groups> mGroupListList, int mGroupPosition)
{
this.mContext = context;
this.mGroupListList = mGroupListList;
this.mGroupPosition = mGroupPosition;
}
#Override
public int getCount()
{
return mGroupListList.get(mGroupPosition).getChildList().size();
}
#Override
public Object getItem(int position)
{
return mGroupListList.get(mGroupPosition).getChildList().get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_group_child, null, false);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
// Implement Your code here what functionality you need.
return convertView;
}
private static class ViewHolder
{
TextView txtName;
}
}
Hope it helps you. If you have any issues let me know
With the help of #Sam idea, done the Horizontal scroll for child elements of ExpandableListView with RecyclerView without any third party plugin.
Demo app: https://github.com/sivailango/ExpandableListView-RecylerChildItems
I am trying to build a layout as shown in the image where the Date(TextView) is shown above the images in GridView and the TextView appears multiple times in view .I am confused on how to implement it. I tried putting TextView in list item but in that case TextView is repeating for each row. Can anyone suggest how to go with this.Reference image attached.
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/lvTimeline"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rlText">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="28 Feb"
android:layout_marginLeft="16dp"
android:layout_alignParentLeft="true"
android:id="#+id/tvDate"/>
</RelativeLayout>
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gvTest"
android:numColumns="3"
android:verticalSpacing="3dp">
</GridView>
gridview_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="116dp"
android:layout_height="116dp"
android:scaleType="fitXY"
android:id="#+id/ivTimeline"
android:src="#android:drawable/sym_def_app_icon"/>
List adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.tvDate = (TextView) view.findViewById(R.id.tvDate);
holder.gvTimeline = (GridView) convertView
.findViewById(R.id.gvTest);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.gvTimeline.setAdapter(new GridAdapter(imagesList));
return view;
}
public static class ViewHolder {
TextView tvDate;
GridView gvTimeline;
}
GridView Adapter :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.gridview_item, parent, false);
holder = new ViewHolder();
holder.ivImage = (ImageView) view.findViewById(R.id.ivTimeline);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.ivImage.setImageResource(getItem(position));
return view;
}
public static class ViewHolder {
ImageView ivImage;
}
Image which I am getting now :
When I click the button in the ListView, I see the toast once. Then further clicks don't show anything when I click away from the button and in an empty space in the ListView, all the button click events that were not responding earlier appear at once (many toasts pop up one after another). Any idea how to fix this?
class Adapter extends ArrayAdapter
{
HashMap<Integer, View> rowViews = new HashMap<Integer, View>();
public Adapter(Context context) {
super(context, R.layout.manage_member_row, members);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final View rowView;
if(rowViews.containsKey(position)) {
rowView = rowViews.get(position);
} else {
rowView = inflater.inflate(R.layout.manage_member_row, parent, false);
((TextView) rowView.findViewById(R.id.manage_member_row_name)).setText(members.get(position).name);
rowViews.put(position, rowView);
}
((Button) rowView.findViewById(R.id.manage_member_row_delete)).setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "btnclick", Toast.LENGTH_SHORT).show();
}
});
Log.i("CRC", "called");
return rowView;
}
//manage_member_row.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:descendantFocusability="blocksDescendants"
android:layout_alignParentLeft="true"
android:layout_height="wrap_content"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:background="#FFFFFF"
android:orientation="vertical">
<TextView
android:id="#+id/manage_member_row_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="name"
android:textSize="18sp"
android:textColor="#53585E"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="15dp" />
<Button
android:id="#+id/manage_member_row_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="0dip"
android:paddingBottom="0dip"
android:paddingLeft="8dip"
android:clickable="true"
android:focusable="true"
android:textSize="18sp"
android:textColor="#4E4E4E"
android:background="#EAEAEA"
android:paddingRight="8dip"
android:textStyle="bold"
android:text="REMOVE"
android:layout_alignParentRight="true"
android:layout_marginRight="15dip" />
</RelativeLayout>
//fragment_manage_members.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"
tools:context="activities.ManageMembersActivity$PlaceholderFragment">
<ListView
android:layout_width="wrap_content"
android:descendantFocusability="blocksDescendants"
android:layout_marginTop="0dip"
android:dividerHeight="2.0dip"
android:divider="#EEEDF3"
android:layout_height="wrap_content"
android:id="#android:id/list" />
</RelativeLayout>
The problem is that sometimes position from getView are not synchronized have that problem before..
Also note that you use a HashMap<Integer, View> just to check if the view is already there that cost a lot of memory and will cause OutOfMemoryException..
so instead of putting it in a hashMap just create a ViewHolder for all your views. and add the object of the ViewHolder to the tag of the View..
example:
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
ViewHolder viewHolder = null;
if(view == null)
{
viewHolder = new ViewHolder();
view = mInflater.inflate(R.layout.chat_online_user_list_view_item, null);
viewHolder.userName = (TextView) view.findViewById(R.id.chat_online_user_name);
view.setTag(viewHolder);
}
else
viewHolder = (ViewHolder) view.getTag();
//DO THE ON CLICK LISTENER HERE
return view;
}
private class ViewHolder
{
private TextView userName;
}
I already implemented my gridview using Android Universal Image Loader, but I need to put a label below every photo.
This is my ac_image_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip"
android:padding="4dip" />
And this is my item_grid_image.xml :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget44"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_x="201px"
android:layout_y="165px"
android:gravity="center_horizontal"
>
<ImageView
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="120dip"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/icon_text"
android:typeface="serif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textStyle="bold"
android:lines="2">
</TextView>
</LinearLayout>
I know that I have to implement it in this function, but I don't know how:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(imageUrlsSmall.get(position), imageView, options);
return imageView;
}
UPDATE: Finally I did it with this code.
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
holder = new ViewHolder();
holder.text = (TextView) view.findViewById(R.id.icon_text);
holder.image = (ImageView) view.findViewById(R.id.image);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.text.setText(album[position].getName());
imageLoader.displayImage(albumsPhoto[position], holder.image, options, animateFirstListener);
return view;
}
Perhaps something like this;
private TextView mInfoView;
OnCreate():
mInfoView = (TextView) findViewById(R.id.icon_text);
getView():
// after imageLoader.displayImage
mInfoView.setBackgroundColor(Color.TRANSPARENT);
mInfoView.setText("Some description");
I want to display some text below each grid image.
Please see my code below.
Please help me in finding why its not working
I am getting the images properly displayed but no text
if i try to display text within image its coming
so it should be something with the layout defined. but i am not able to debug
adaptor code :
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.griditems, null);
holder = new ViewHolder();
holder.text1 = (TextView) convertView
.findViewById(R.id.grid_item_text);
Log.i(TAG, holder.text1.toString());
holder.image = (ImageView) convertView
.findViewById(R.id.grid_item_image);
// if it's not recycled, initialize some attributes
holder.image.setImageResource(gridItemIds[position]);
holder.text1.setText(gridTitles[position]);
//holder.image.setScaleType(ImageView.ScaleType.FIT_XY);
// holder.image.setPadding(20, 20, 20, 20);
convertView.setLayoutParams(new GridView.LayoutParams(Utils
.getLayoutParameter(), Utils.getLayoutParameter()));
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView text1;
ImageView image;
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/GridItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
>
<ImageView android:id="#+id/grid_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView android:id="#+id/grid_item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#000000"
>
</TextView>
</LinearLayout>
gridview :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/text1view" android:textStyle="bold"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:gravity="center_horizontal" android:background="#drawable/title_bar"
/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:verticalSpacing="50dip"
android:horizontalSpacing="10dp" android:numColumns="3"
android:stretchMode="columnWidth"
android:layout_below="#+id/text1view"
android:gravity="center"
android:layout_centerHorizontal="true"
android:background="#drawable/home_bg"
/>
</LinearLayout>
I used your xml but with a simple array adapter that I wrote and everything work perfectly, try to replace your adapter with mine and let me know, thanks.
class ItemsAdapter extends ArrayAdapter<String> {
public ItemsAdapter(Context context, List<String> list) {
super(context, R.layout.griditems, list);
}
#Override
public View getView(final int position, View row, final ViewGroup parent) {
final String item = getItem(position);
ItemWrapper wrapper = null;
if (row == null) {
row = getLayoutInflater().inflate(R.layout.griditems, parent, false);
wrapper = new ItemWrapper(row);
row.setTag(wrapper);
} else {
wrapper = (ItemWrapper) row.getTag();
}
wrapper.refreshData(item);
return row;
}
}
static class ItemWrapper {
TextView text;
ImageView img;
public ItemWrapper(View row) {
text = (TextView) row.findViewById(R.id.grid_item_text);
img = (ImageView) row.findViewById(R.id.grid_item_image);
}
public void refreshData(String item) {
img.setImageResource(R.drawable.image_1);
text.setText(item);
}
}
Also try using RelativeLayout too, placing the TextView underneath the ImageView by using
android:layout_below="#id/grid_item_image"
It'll place it underneath the image, however, if you have the option to use the Graphical Layout, dragging it where you want it in conjunction with the image will set all the parameters for you instead of typing them out.