View.getChildAt findViewById returns NPE - android

My app utilizes RecyclerView. Here's the xml for the content of each item in the RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cvExpenses"
android:layout_height="wrap_content"
android:layout_width="match_parent"
card_view:cardCornerRadius="5dp"
android:layout_margin="5dp"
card_view:cardBackgroundColor="#009dde"
>
<LinearLayout
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dip">
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0"
android:visibility="gone"
android:id="#+id/tvGuestID" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:id="#+id/tvGuestName"
android:textColor="#ffffff" />
<Switch
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:id="#+id/swCheckIn"
android:clickable="true"
android:textOff="no"
android:textOn="yes" />
</LinearLayout>
</android.support.v7.widget.CardView>
Now I got the index of the item in my RecyclerView that I want to toggle it's switch, so here's how I did it:
indexOfGuestIdToCheckIn = listGuestID.indexOf(guestIdToCheckIn);
View view = rvGuestList.getChildAt(indexOfGuestIdToCheckIn);
Switch swCheckIn = (Switch) view.findViewById(R.id.swCheckIn);
swCheckIn.setChecked(true);
I thought the code above would toggle the switch of the selected item in my recyclerview, but instead it returns NullPointerException at Switch swCheckIn = (Switch) view.findViewById(R.id.swCheckIn);

Your views are not inflated yet if they are not visible on screen As this answer has stated. The link also provides an interesting solution you can check.
For your case you should track your models/objects inside on the adapters getView() and decide if it should be checked or not by checking it against a list of your IDs and what values that it should have.
HashMap<Long, Boolean> hashMap = new HashMap<>();
// put values on hashmap
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final <OBJECT> item = getItem(position);
Switch swCheckIn = (Switch) view.findViewById(R.id.swCheckIn);
Boolean isChecked = hashMap.get(item.getId())
if(isChecked != null && isChecked) {
swCheckIn.setChecked(isChecked);
}
}

Related

Expandable List view with recycler list view as child

As shown in the image, I am able to render the view. But the onChildClick event of Expandable view is not getting triggered.
Also the touch event in the adapter is not responding. My layout details are mentioned below.
The full source code for this can be found in here.
main_activity.xml
<ExpandableListView
android:id="#+id/list_brands"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#null"
android:groupIndicator="#null"
android:dividerHeight="5dp" />
item_parent.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="#+id/text_brand"
android:textSize="18dp"
android:text="Text"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/image_indicator"
android:src="#drawable/ic_keyboard_arrow_down_black_18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
item_group_child.xml
<android.support.v7.widget.RecyclerViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mobiles"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
item_child.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp">
<ImageView
android:id="#+id/image_mobile"
android:layout_width="70dp"
android:adjustViewBounds="true"
android:layout_height="120dp" />
<TextView
android:id="#+id/text_mobile_model"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<TextView
android:id="#+id/text_mobile_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
</LinearLayout>
**My Solution : **
Touch events are directly passed to the UI Elements of the View holder in the Recycler List view. But to give the touch event to the whole layout I have added the transparent button on top of child_item layout and added a click listener. Following is the updated child_item.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_height="match_parent"
android:layout_width="match_parent" >
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/dummy_click"
android:background="#android:color/transparent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:padding="10dp"
android:background="#color/colorGrey"
>
<ImageView
android:id="#+id/img_subcategory"
android:layout_gravity="center"
android:src="#mipmap/ic_launcher"
android:layout_marginTop="10dp"
android:layout_width="180dp"
android:layout_height="90dp"
android:scaleType="fitXY"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sub Category"
android:textColor="#color/colorWhite"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:id="#+id/txt_subcategory"
android:textSize="#dimen/app_text_title"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
Theory
ExpandableListView, child click sample:
for click on child, you can handle this way.
getExpandableListView().setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// your code...
}
});
Expandable RecyclerView, useful library and easy item click support:
This blog post by Hugo shows an alternative way without listeners:
http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/
It comes down to adding these lines:
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
When using this class:
public class ItemClickSupport {...}
And this value in ids.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="item_click_support" type="id" />
</resources>
Why doesn't RecyclerView have onItemClickListener()? And how RecyclerView is different from Listview?
Since the introduction of ListView, onItemClickListener has been
problematic. The moment you have a click listener for any of the
internal elements the callback would not be triggered, but it wasn't
notified or well documented (if at all) so there was a lot of
confusion and SO questions about it.
OnItemClickListener doesn't work with ListView item containing button
Just add this line into the item views instead of listView itself
android:focusable="false"
Check more detail about this from: Android custom ListView unable to click on items
Practice
#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.item_group_child, parent, false);
childHolder = new ChildHolder();
// Fix listview onclicklistener issue: inner views can not be focusable
childHolder.YOUR_INNER_BUTTON = (YOUR_BUTTON_TYPE) convertView.findViewById(R.id.YOUR_BUTTON_ID);
childHolder.YOUR_INNER_BUTTON.setFocusable(false);
convertView.setTag(childHolder);
}
else {
childHolder = (ChildHolder) convertView.getTag();
}
childHolder.horizontalListView = (RecyclerView) convertView.findViewById(R.id.mobiles);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
childHolder.horizontalListView.setLayoutManager(layoutManager);
MobileAdapter horizontalListAdapter = new MobileAdapter(context, brands.get(groupPosition).mobiles);
childHolder.horizontalListView.setAdapter(horizontalListAdapter);
return convertView;
}
Added two lines to your code based on my legacy code:
// Creates a ViewHolder and store references to the children views (collapsed)
holder = new ViewHolderChildren();
holder.textLine = (TextView) convertView.findViewById(R.id.usersTextLine);
holder.subtextLine = (TextView) convertView.findViewById(R.id.usersSubtextLine);
holder.iconLine = (ImageView) convertView.findViewById(R.id.usersIconLine);
holder.buttonLine = (ImageButton) convertView.findViewById(R.id.usersButtonLine);
holder.infoLine = (TextView) convertView.findViewById(R.id.usersInfoLine);
holder.infoLine.setVisibility(TextView.GONE);
holder.userprofileButton = (ImageButton) convertView.findViewById(R.id.usersUserprofileBtn);
holder.buttonLine.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// if gone, set visible and arrow up image
if (holder.infoLine.getVisibility() == TextView.GONE) {
holder.infoLine.setVisibility(TextView.VISIBLE);
holder.buttonLine.setImageLevel(1);
}
// if visible, set gone and arrow down image
else {
holder.infoLine.setVisibility(TextView.GONE);
holder.buttonLine.setImageLevel(0);
}
}
});
//fixed listview onclicklistener bug: inner views can not be focusable
holder.buttonLine.setFocusable(false);
convertView.setTag(holder);

listview and edittext softkeyboard

I have custom template with edittext field. When I click on "next" button on softkeyboard it move focus only two time - than button changed to "OK". List have 12 items.
Any way to navigate to all items, not only 2?
Can you help me please?
Im use this template for listview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="3dp" >
<TextView
android:id="#+id/head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:paddingBottom="3dp"
android:paddingTop="3dp" >
<EditText
android:id="#+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="left"
android:inputType="number" >
<requestFocus />
</EditText>
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:width="100dp" />
</LinearLayout>
</LinearLayout>
And this xml for listview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/calk_1"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="382dp"
android:divider="#color/reddivider"
android:dividerHeight="#dimen/twodp"
android:focusable="true"
android:focusableInTouchMode="true"
android:smoothScrollbar="true" >
</ListView>
</LinearLayout>
Also, here my adapter right now:
public View getView(int position, View convertView, ViewGroup parent){
// assign the view we are converting to a local variable
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_view, null);
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list. (The ArrayAdapter
* iterates through the list we sent it)
*
* Therefore, i refers to the current Item object.
*/
CalcItem i = objects.get(position);
int last=getCount()-1;
if (i != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView hd = (TextView) v.findViewById(R.id.head);
TextView tx = (TextView) v.findViewById(R.id.text);
TextView ds = (TextView) v.findViewById(R.id.description);
EditText vl = (EditText) v.findViewById(R.id.value);
if (position==0){
vl.setNextFocusUpId(last);
vl.setNextFocusDownId(1);
} else if (position==last){
vl.setNextFocusDownId(0);
} else {
vl.setNextFocusDownId(position+1);
}
if (hd != null){
hd.setText(i.getHead());
}
if (tx != null){
tx.setText(i.getText());
}
if (ds != null){
ds.setText(i.getDescription());
}
if (vl != null){
vl.setText(Integer.toString(i.getValue()));
}
}
// the view must be returned to our activity
return v;
}
Use android:nextFocusUp="id" and android:nextFocusDown="id" - as described in the documentation.
Here's an example from the docs:
<LinearLayout
android:orientation="vertical"
... >
<Button android:id="#+id/top"
android:nextFocusUp="#+id/bottom"
... />
<Button android:id="#+id/bottom"
android:nextFocusDown="#+id/top"
... />
</LinearLayout>
As far as I know, Edit texts doesnt work well in ListViews and Recycler views,
I'll Recommend you to inflate separate views multiple times instead of making a ListView if you are dealing with edit texts.

keyboard reset radiogroup value

I have a custom ListView with a radiogroup in each row.
When I change the checked radio button, I call a dialog with some edittext fields (using the onCheckedChanged() method). But, when i focused an edittext to write something, I lose all the checked radiobuttons which are covered by keyboard, and the group returns to the default option selected.
can someone help me?
List adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ContractItemHolder cih = new ContractItemHolder();
if (row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(R.layout.row_proposals_item, parent, false);
cih.setTvItemTitle((TextView)row.findViewById(R.id.textViewItemTitle));
cih.setRgItemStatus((RadioGroup)row.findViewById(R.id.radioGroupStatus));
row.setTag(cih);
}else {
cih=(ContractItemHolder)row.getTag();
}
final ContractItem ci = list.get(position);
cih.getRgItemStatus().setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
groupSel = group;
int selected = group.getCheckedRadioButtonId();
Dialog d;
switch (selected) {
case R.id.radioAccepted:
d = createDialog(context, ACCEPTED_CODE, ci, selected);
d.show();
break;
case R.id.radioRefused:
d = createDialog(context, REFUSED_CODE, ci, selected);
d.show();
break;
default:
break;
}
}
});
cih.getTvItemTitle().setText(ci.getDescItem());
return row;
}
List item layout (the row..)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:gravity="center">
<TextView
android:id="#+id/textViewItemTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_weight="3"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioGroup
android:id="#+id/radioGroupStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1"
android:showDividers="middle">
<RadioButton
android:id="#+id/radioNull"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Non Proposto"
android:checked="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioButton
android:id="#+id/radioPending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="In trattativa"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Blue"/>
<RadioButton
android:id="#+id/radioAccepted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Accettato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Green"/>
<RadioButton
android:id="#+id/radioRefused"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rifiutato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Red"/>
</RadioGroup>
</LinearLayout>
Dialog impl
private Dialog createDialog(Context context, final int code, ContractItem item,final int selected){ //type: refused, accepted
d = new Dialog(context);
d.setTitle(item.getDescItem());
d.setContentView(R.layout.layout_dialog_prop);
d.getWindow().setLayout(900, LayoutParams.WRAP_CONTENT);
d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Button btnOK = (Button)d.findViewById(R.id.buttonPropOK);
Button btnCancel = (Button)d.findViewById(R.id.buttonPropCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
return d;
}
Dialog layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="50dp" >
<EditText
android:id="#+id/editTextDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="Sconto proposto"
android:inputType="number"
android:textAppearance="?android:attr/textAppearanceLarge" >
<requestFocus />
</EditText>
<Spinner
android:id="#+id/spinnerScuse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="gone" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:ems="10"
android:gravity="top"
android:hint="Note"
android:inputType="textMultiLine"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<View
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="30dp"
android:background="#android:color/holo_blue_light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/buttonPropCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Annulla"
android:textColor="#android:color/holo_blue_light" />
<View
android:id="#+id/view1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light" />
<Button
android:id="#+id/buttonPropOK"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Ok"
android:textColor="#android:color/holo_blue_light" />
</LinearLayout>
</LinearLayout>
You are partially aware of the list-item view recycling process.
The ListView component doesn't generate view for each item in the list. So, there won't be 15 of them in your case. There will be just as many as can fit on the screen. When you scroll the list, the old items, which are no longer visible, are recycled. The getView is then called with convertView != null and the adapter is giving you an opportunity to update this recycled item view. This is done for performance reasons - just imagine an adapter having 10000 items (not a rare thing in commercial applications). Should it create all 10000 list item views? Imagine the performance you would have while scrolling such a list...
In your getView() code, you update an item view only partially - you always set item title in this line:
cih.getTvItemTitle().setText(ci.getDescItem());
When an fresh item view is created (i.e. the convertView == null) the radio group has a default selection, which may be fine in your case.
However, when the item view is recycled (i.e. the convertView != null), then you:
set a change listener in this line:
cih.getRgItemStatus().setOnCheckedChangeListener(...);
set item title:
cih.getTvItemTitle().setText(ci.getDescItem());
But you never set the checked radio group item. That means, it will have a value which was last set for this instance of item view - not for that position. You should store that information - probably in ContractItem, update it when the radio group item is selected and finally - retrieve it when convertView != null and set selected item of the radio group to the correct value.
You probably see this defect when you open up a dialog - the visible area of a ListView becomes smaller as the soft keyboard opens. This causes the ListView to remove unnecessary (technically: no longer visible) item views. When you hide the soft keyboard, the ListView area becomes larger again thus causing it to create missing item views. Unfortunately, you don't save and restore the last selected item of the radio group and so, after creation the newly visible items have the default item selected in the radio group.

problem with custom ListView showing 3 vertical TextViews

im trying to display 3 TextViews as a custom row design in a ListView. Unfortunatly, only 2 TextViews ( row_title and row_postcode_city) are visible...
Maybe somebody has an idea?
Regards,
float
Code of my ArrayAdapter:
private class PartnerAdapter extends ArrayAdapter<Partner> {
private ArrayList<Partner> items;
public PartnerAdapter(Context context, int textViewResourceId, ArrayList<Partner> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.partner_suche_ergebnis_row, parent, false);
}
Partner o = items.get(position);
if (o != null) {
TextView title = (TextView) v.findViewById(R.id.row_title);
TextView subtitle = (TextView) v.findViewById(R.id.row_subtitle);
TextView postcode_city = (TextView) v.findViewById(R.id.row_postcode_city);
if (title != null) {
title.setText(o.getTitle());
}
if(subtitle != null){
subtitle.setText(o.getSubtitle());
}
if(postcode_city != null){
subtitle.setText(o.getPostcode() + " " + o.getCity());
}
}
return v;
}
}
XML of the custom row design:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="0dip"><!--
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="6dip"
android:src="#drawable/icon" />
--><LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:id="#+id/row_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="bold"/>
<TextView
android:id="#+id/row_subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/row_postcode_city"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
Try to use the following xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dip">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:id="#+id/row_title"
android:text="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="bold"/>
<TextView
android:id="#+id/row_subtitle"
android:text="2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="3"
android:id="#+id/row_postcode_city"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
Check it now.
Change your LinearLayout to "wrap_content" on layout_height
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
Also, I don't know why you have a LinearLayout inside a LinearLayout. Since this xml is only for individual rows. Each row will be a horizontal LinearLayout, the second one being unnecessary as ListView automatically lists rows vertically.
Finally, the root LinearLayout should use minHeight for the default Item Height, not layout_height.
android:minHeight="?android:attr/listPreferredItemHeight"
This should be your xml file (unless you really need the second LinearLayout for some odd reason)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:padding="0dip">
<TextView
android:id="#+id/row_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="bold"/>
<TextView
android:id="#+id/row_subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/row_postcode_city"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Sorry for offtopic, but I here some useful tips from me
You have a LOT of needless (and flat out wrong) stuff going on here:
Partner o = items.get(position);
if (o != null) {
You should get something for every position, if item retuns null that means you are doing something wrong. In your case, if you get null you just return reused old, or brand new row, which will confuse the user by displaying the old data, or no data at all.
if (title != null) {
You have 2 ways of getting View object of your row, by inflating, or getting it from recycler (convertView). And recycler will ALLWAYS return the right type of View, so those check are useless since your components will always be found.

ListView with clickable/editable widget

Is it possible to use a OnItemClickListener on a ListView when the Items layout has a clickable/editable widget (RadioButton,EditText, or CheckBox)?
You might want to take a look at this issue. Having a focusable item in a row of a ListView causes the OnItemClickListener NOT to be invoked. However, that does not mean you cannot have focusable/clickable items in a row, there are some workarounds like this one.
Also, you can take a look at the Call Logs screen. It has a ListView with clickable item(the call icon on the right).
See Source code here
Quoting comment #31 in the link mentioned by Samuh (which solved the problem for me):
In fact you can add it to the layout XML (if inflated by one): android:descendantFocusability="blocksDescendants".
Adding here JIC that webpage is down in the future.
If any row item of list contains focusable or clickable view then OnItemClickListener won't work.
row item must be having param like android:descendantFocusability="blocksDescendants"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical" >
// your other widgets here
</LinearLayout>
Tried many complex solutions, but this was the simplest one that worked:
Just use android:focusable="false" as in:
<CheckBox
android:id="#+id/fav_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false" />
Two best solution
Add android:descendantFocusability="beforeDescendants" to listView
in xml OR
Set given two attributes to false
like
android:focusable="false"
android:focusableInTouchMode="false"
Then it will handle the listView row item child(Button,EditText etc) events instead of listView.setOnItemClick .
I fixed my problem different , in my item I have more than one LinearLayout
so if you give id to your linearayout and setOnclickListener in adapter class it will work, only original effect of touching will dissapear.
but this link Making a LinearLayout act like an Button is usefull to make linearlaout act like button on click
item
<?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="match_parent"
android:layout_marginTop="10dp">
<TextView
android:id="#+id/txt_item_followers_name"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center|start"
android:paddingLeft="15dp"
android:text="Ali"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/imageView"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/txt_item_followers_name"
android:layout_marginLeft="10dp"
android:src="#drawable/puan_icon" />
<TextView
android:id="#+id/txt_item_followers_mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView"
android:layout_toEndOf="#+id/imageView"
android:background="#color/red_400"
android:paddingLeft="10dp"
android:text="25.5"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:id="#+id/linear_one"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/txt_item_followers_name"
android:background="#color/red_400"
android:orientation="vertical">
<ImageView
android:id="#+id/btn_item_followers_2b_follow"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_marginLeft="10dp"
android:src="#drawable/follow_buton" />
</LinearLayout>
</RelativeLayout>
inside getView method
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.deneme, null);
final Followers2 myObj = myList.get(position);
LinearLayout linear_one = (LinearLayout) view.findViewById(R.id.linear_one); // HERE WE DOMUNÄ°CATE IT
linear_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(parentActivity, "One Two", Toast.LENGTH_SHORT).show();
}
});
TextView name = (TextView) view.findViewById(R.id.txt_item_followers_name);
TextView mark = (TextView) view.findViewById(R.id.txt_item_followers_mark);
final ImageView btn_follow = (ImageView) view.findViewById(R.id.btn_item_followers_2b_follow);
name.setText(myObj.getName());
mark.setText(myObj.getScore());
/* if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Followers2 myObj = myList.get(position);
if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
}
});*/
return view;
}

Categories

Resources