Interactive with TextView in each row of ListView - android

I have an list View with two Item in each row is two TextView.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="vertical">
<TextView
android:id="#+id/txtInfo"
android:layout_width="wrap_content"
android:layout_height="30sp"
android:layout_gravity="right"
android:textSize="12sp"
android:visibility="gone"
android:textColor="#android:color/darker_gray" />
<LinearLayout
android:id="#+id/contentWithBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#drawable/my_textview_border"
android:paddingLeft="10dp"
android:paddingBottom="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/txtMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:padding="10dp"
android:maxWidth="240dp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Now I want to show the hidden TextView just on the row I click with onItemClick(AdapterView<?> parent, View view, int position, long id) method but how can I set an detail id for each TextView. I mean the TextView just VISIBLE in the row I touch, not all of that TextView in other row.

Extend your class Activity by implements OnItemClickListener
use yourList.setOnItemClickListener(this); in onCreate()
Override onItemClick using this way:
s
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
TextView tv = (TextView) view.findViewById(R.id.txtMessage);
tv.setVisibility(View.VISIBLE);
}
do not forget to override your getView() arrayAdapter method:
a
public View getView(int position, View convertView, ViewGroup list) {
View element;
if (convertView == null) {
element = View.inflate(ctx, R.layout.yourlayout, null);
} else {
element = convertView;
}
///setup your listview element
return element;
}
EDIT
to change all data for textview I will work in such way:
yourarrayadater.setupmydata();
yourarrayadater.notifyDataSetChanged()
after that arrayadapter will redraw using getView.
So, use again
public View getView(int position, View convertView, ViewGroup list) {
View element;
if (convertView == null) {
element = View.inflate(ctx, R.layout.yourlayout, null);
} else {
element = convertView;
}
TextView tv = (TextView) element.findViewById(R.id.txtMessage);
///SETUP YOUR tv for each row
return element;
}

Related

Custom list adapter onClick method returning a null view id

In creating a custom list adapter to be able to click different elements in a single row entry and start different activities, I ran across a problem where my findViewById() method was returning null. Additionally, only the first item in my ListView calls the onClick method; the other rows don't register clicks.
public class CustomListAdapter extends SimpleAdapter implements View.OnClickListener {
Context context;
TextView habitId;
Intent intent;
public CustomListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.habit_entry, null);
}
TextView tv = (TextView) v.findViewById(R.id.habitTitle);
tv.setOnClickListener(this);
ImageView iv = (ImageView) v.findViewById(R.id.plus);
iv.setOnClickListener(this);
return super.getView(position, convertView, parent);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.habitTitle:
Log.d("Test", "habitid = " + v.findViewById(R.id.habitId));
break;
case R.id.plus:
Log.d("Test", "plus clicked");
default:
break;
}
}
When the code is run, the habitTitle case of onClick prints
D/NULL: habitid = null
habit_entry
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:src="#drawable/ic_plus"
android:id="#+id/plus"
android:scaleType="centerCrop"
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:background="#9bfcff" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/habitId"
android:visibility="gone" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="difficulty"
android:id="#+id/habitDifficulty"
android:gravity="right"
android:paddingLeft="15dp"
android:layout_alignParentBottom="true"
android:layout_alignRight="#+id/habitTitle"
android:layout_alignEnd="#+id/habitTitle"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/plus"
android:layout_above="#id/habitDifficulty"
android:layout_alignWithParentIfMissing="true"
android:text="Your new habits go here!"
android:id="#+id/habitTitle"
android:padding="5dp"
android:textColor="#444444"
android:textSize="20sp"
android:textStyle="bold"
android:layout_alignParentStart="false"
android:gravity="right"
android:allowUndo="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="frequency"
android:id="#+id/habitFrequency"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
call in MainActivity
if(habitList.size() != 0) {
ListView listView = (ListView) findViewById(android.R.id.list);
ListAdapter adapter = new CustomListAdapter(
this, habitList, R.layout.habit_entry, new String[]{"habitId", "title", "difficulty", "frequency"}, new int[]{
R.id.habitId, R.id.habitTitle, R.id.habitDifficulty, R.id.habitFrequency});
listView.setAdapter(adapter);
}
The list populates perfectly, so I'm not sure why I'm having so much trouble with my adapter.
I see a couple problems here. You are inflating the View yourself and then returning the View returned by calling super.getView(position, convertView, parent);. You should instead rely on super.getView(position, convertView, parent); to create the View for you since you are using the default implementation like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
v.findViewById(R.id.habitTitle)
.setOnClickListener(this);
v.findViewById(R.id.plus)
.setOnClickListener(this);
return v;
}
Also v.findViewById(R.id.habitId)); is returning null inside onClick() because the variable v itself is the TextView with id = R.id.habitId.
You set the visibility of the habitId textview to gone.
The textview will not be inflated and is null.
You can read more information about visibility in the android documentation

Android: Horizontal Scroll for ExpandableListView Childs

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

Iterating the ListView and change content of some rows (ListItem)

I have a ListView whose ListItems(RelativeLayout) have
A textView and two ImageButtons inside a LinearLayout.
Here is the xml of my ListItem;
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="#+id/list_item_quote"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="15dp"
android:paddingTop="15dp"
style="#style/quote_text"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/lytShareLike"
android:layout_gravity="center"
android:gravity="center"
android:visibility="gone"
android:layout_margin="1dp"
android:layout_alignLeft="#id/list_item_quote"
android:layout_alignTop="#id/list_item_quote"
android:layout_alignRight="#id/list_item_quote"
android:layout_alignBottom="#id/list_item_quote">
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="centerInside"
android:id="#+id/btnShare"
android:background="#null"
android:onClick="quoteShareClick"
android:src="#drawable/share"
android:layout_marginRight="10dp"
/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="centerInside"
android:id="#+id/btnLike"
android:background="#null"
android:src="#drawable/heartnot"
android:onClick="quoteLikeClick"
/>
</LinearLayout>
</RelativeLayout>
I have ItemClickListener which sets the LinearLayout visible when the ListItem is clicked. There is no problem until here.
What I want to do is, after clicking a ListItem, if the user clicks another ListItem, the other unclicked Listitems' LinearLayouts should be GONE again.
Here is my onClickListener;
listQuotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
LinearLayout lytShareLike = (LinearLayout) view.findViewById(R.id.lytShareLike);
for (int i = 0; i < listQuotes.getAdapter().getCount(); i++) {
if (position != i && i != 0) {
LinearLayout lnrTemp = (LinearLayout) listQuotes.getAdapter().getView(i, null, null).findViewById(R.id.lytShareLike);
lnrTemp.setVisibility(View.GONE);
}
}
}
});
The for iteration iterates the items and LinearLayouts as expected but the LinearLayouts are still VISIBLE
What am I missing?
you can control it by using below code:
//...
int index = -1;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
index = position;
mAdaper..notifyDataSetChanged();
}
//...
in the adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//...
Holder holder;
if(convertView == null) {
convertView = ....;
holder = new Holder(convertView);
convertView.setTag(holder);
}
holder = (Holder) convertView.getTag();
if(index == position){
holder.linearLayout.setVisibility(View.VISIBLE);
} else {
holder.linearLayout.setVisibility(View.GONE);
}
//...
return convertView;
}

button in fragmentlist only responds once, then "releases" when clicking on the row

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;
}

Android getView method do not read textView

I have ListAdapter there is getView(); method. This is a code for method:
#Override
public View getView(int idx, View view, ViewGroup parent)
{
if(view == null)
{
LayoutInflater vi = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.check, null);
}
return view;
}
And this is check.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false" />
<TextView
android:id="#+id/checkedTextView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/checkBox1"
android:layout_alignBottom="#+id/checkBox1"
android:layout_toRightOf="#+id/checkBox1"
android:textColor="#615742"
android:textSize="18sp" />
</RelativeLayout>
The problem is that it reads only checkbox. And it igonres my TextView. If I write in xml file only checkedtextview then text appears but then I can not implement checkbox. What is a problem in my code that it ignores textView and it shows only checkbox?
#Override
public View getView(int idx, View view, ViewGroup parent)
{
if(view == null)
{
LayoutInflater vi = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.check, null);
}
TextView tv = (TextView) view.findViewById(R.id.checkedTextView1);
tv.setText("XXXXXXXX");
return view;
}

Categories

Resources