I have a ListView, each row of which has three TextViews in it. For some reason, as I scroll through the ListView, I'm not able to click on some of the rows. There doesn't seem to be any particular pattern to it. I initially thought this was a focus issue, so I added some statements to remove clickability and focus from the TextViews, but that has not resolved it. Here is the relevant portion of my code:
questionsArrayAdapter = new ArrayAdapter<String>(this, R.id.number, questionsArrayList) {
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (row == null) {
// ROW INFLATION
row = inflater.inflate(R.layout.questionlistitem, parent, false);
}
TextView number = (TextView) row.findViewById(R.id.number);
TextView answer = (TextView) row.findViewById(R.id.answer);
TextView section = (TextView) row.findViewById(R.id.section);
number.setFocusable(false);
number.setClickable(false);
answer.setFocusable(false);
answer.setFocusable(false);
section.setFocusable(false);
section.setClickable(false);
Here is questionlistitem.xml:
<?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:orientation="horizontal" >
<TextView
android:id="#+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:visible="false" />
<TextView
android:id="#+id/answer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_marginRight="5dip"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingEnd="10dip"
android:paddingStart="6dip"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<TextView
android:id="#+id/section"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:visible="true" />
</LinearLayout>
Here is my standard listener:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println("got clicked");
}
Does anyone know what the problem could be?
I think you're on the right track in thinking that this is an issue where your TextViews are drawing focus away from your click events. I found this discussion of what may be the same problem filed as a bug report for the source, however this was years ago and it seems that the official word was "working as intended." At the link, the two proposed solutions seems to be using the android:focusable="false" attribute on your TextViews in the xml (not sure if this is equivalent to doing it programmatically, as you've tried) or calling setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS); on convertView before it gets returned.
Something else that may be contributing to the problem is how your TextViews are being arranged in your xml file. The children of a horizontal LinearLayout should usually not have a layout_width of match_parent or fill_parent. This causes these views to expand to fill the length of the parent view, possibly overlapping their siblings and potentially causing weirdness both visually and when trying to interact with/click the children. You may want to consider using the layout_weight attribute, or making the parent a RelativeLayout, where you'll have more control over the position of the views.
Related
Here is my custom list adapter's getView() method
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.listview_row, null, false);
}
TextView textName = row.FindViewById<TextView>(Resource.Id.textName);
textName.Text = mItems[position];
return row;
}
And here is my listview_row.xml file which is 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="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<TextView
android:text="Name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textName"
android:padding="10dp"/>
</LinearLayout>
I am curious about how list view sizes each row.
When I inflate the "listview_row" into a view and put it in the ListView, I am expecting that the first inflated view will take up whole space of ListView because this view has attributes of layout_width="match_parent" and layout_height="match_parent".
However, when i run this code, each row of the listView size is based on the row's content in the textView. How is it possible? is it something to do with the parameters of inflate() method?
Could you guys explain how ListView sizes its row?
Follow this way to program row list for adapter.
<?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="ADD_ROW_HEIGHT"
>
<TextView
android:text="Name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/textName"
android:padding="10dp"/>
</LinearLayout>
I think you can consider ListView as an area that allows other views to be displayed within it, it's a container. In your case having the view (the TextView) as wrap_content is saying only take up as much space (vertically) as needed. As such, the ListView can possibly hold more than one.
If it's the actual calculations that you want to know, then although I recall seeing something, I can't recall when or where I saw that info.
I try to set the list item row height in xml files.For example, I have a listView and a corresponding listAdapter, this adapter inflate a view from a xml file:
<?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="60dp"
android:orientation="horizontal" >
<ImageView
android:id="#+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_right"/>
<TextView
android:id="#+id/info"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:padding="20dp"
android:textSize="16sp"
android:textColor="#f96f00"
android:layout_gravity="center"
android:lines="1"
android:ellipsize="end"
/>
<TextView
android:id="#+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="12sp"
android:paddingRight="10dp"
/>
</LinearLayout>
However this 60dp has no effect, no matter how much this height you have set the inflated row view has a fixed height. When I adjust the textview inside the layout, the row height has changed. Why this happen, how could i assign the height of the list item row to a fixed metric?
I have looked the source code for LayoutInfalter's infalte function , if the root is null, then the LayoutParams is not generate for this view, and a default layoutParams will be used when attached to others. If root is set, then inflater will generate and set a LayouParams for this view. However, the attachToRoot cannot be set to true, cause the View get will be added to the adapter view soon.
View v = inflater.inflate(R.layout.filtered_trip_row, parent,false);
This solved my question .
Alright alright, no need to panic it happenes.
in your getView of adapter, just write this code before returning the view.
// Just reset the layout parms before return
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
60*3); // put proper dp pixel conversion here, in hdpi it 3px = 1dp
view.setLayoutParams(params);
return view;
Please check 'parent' parameter to null while inflating your row,
View v = inflater.inflate(R.layout.filtered_trip_row, null);
Instead try this,
View v = inflater.inflate(R.layout.filtered_trip_row, parent);
Now try to set your height inside getView.
Hope this helps you.
i need to have a gridview of linearlayouts. Each linearLayout must have a imageview and a relativelayout children with more childrens on it.
I'm searching for tutorials/examples of creating gridviews of LinearLayouts but i can't find nothing.
Someone haves a tutorial or can give me some examples or help to do this?
thanks
Yes, it's possible and is quite simple indeed. When you use your GridView, provide an Adapter to it. In the adapter's getview method, you can create any view you like and return it. For example, you can inflate a view from XML - and that xml may contain a LinearLayout. Alternatively, you can create a linear layout on the fly in that method and add other components to it.
Have a look at this article on Google: http://developer.android.com/resources/tutorials/views/hello-gridview.html
Update: a small example
In your res/layout/item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="0dip"
android:paddingBottom="0dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/TxtName"
android:scrollHorizontally="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:layout_weight="0.2"
android:padding="2dp"/>
<TextView android:id="#+id/TxtPackage"
android:scrollHorizontally="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:textColor="#android:color/black"
android:padding="2dp"/>
</LinearLayout>
Then in your adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//get the item corresponding to your position
LinearLayout row = (LinearLayout) (convertView == null
? LayoutInflater.from(context).inflate(R.layout.item, parent, false)
: convertView);
((TextView)row.findViewById(R.id.TxtName)).setText("first text");
((TextView)row.findViewById(R.id.TxtPackage)).setText("second text");
return row;
}
I'm trying to create a layout containing, among other things, a LinearLayout. The XML for the whole screen is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/fileSelView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Spinner android:id="#+id/dirListSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<Spinner android:id="#+id/fileTypeSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
<EditText android:id="#+id/fileNameTF"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/fileTypeSpinner"/>
<LinearLayout android:id="#+id/centerBox"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/dirListSpinner"
android:layout_above="#+id/fileTypeSpinner"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true">
<ListView android:id="#+id/dirView" android:background="#f00"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1"/>
<RelativeLayout android:id="#+id/buttonBox" android:background="#0f0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="0">
<Button android:id="#+id/upButton"
android:text="Up"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/mkdirButton"
android:text="MkDir"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/upButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/okButton"
android:text="OK"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/mkdirButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/cancelButton"
android:text="Cancel"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/okButton"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
The result of this layout looks like this:
The LinearLayout itself is laid out the way I want, within its parent, but its contents come out all wrong. It has two children: a ListView on the left and a RelativeLayout on the right. The ListView should take up all the available height, and as much width as possible, while the RelativeLayout should be a small as possible and vertically centered within its parent. Instead, the ListView ends up being way too narrow, and the RelativeLayout grows to fill the space, despite the ListView having android:layout_weight="1" and the RelativeLayout having android:layout_weight="0". Also, the RelativeLayout is aligned with the top of its parent, despite having android:gravity="center_vertical".
What am I doing wrong?
UPDATE
OK, I changed android:gravity="center_vertical" to android:layout_gravity="center" on the RelativeLayout, and now it is vertically centered within its parent, as desired.
Regarding the layout weight issue, I tried changing android:layout_width="fill_parent" to android:layout_width="0px" on the ListView, but that didn't work; I'm getting the same result as before, with the ListView way too narrow and the RelativeLayout expanding to take up the available space.
The layout now looks like this: http://thomasokken.com/layout-problem2.png
Note that the buttons in the RelativeLayout are not correctly centered horizontally. It's as if the RelativeLayout got sized and laid out correctly at first, and then grew towards the left later, without re-laying out its children.
I haven't been able to get the ListView to get sized properly using a RelativeLayout parent, either. Could it be resizing itself in response to a setAdapter() call? I'm using a custom ListAdapter class whose getView() method returns RelativeLayout objects:
public View getView(int position, View convertView, ViewGroup parent) {
File item = items[position];
if (convertView == null) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.file_selection_dialog_row, null);
ImageView icon = (ImageView) convertView.findViewById(R.id.fdrowimage);
icon.setImageResource(item.isDirectory() ? R.drawable.folder : R.drawable.document);
}
TextView text = (TextView) convertView.findViewById(R.id.fdrowtext);
text.setText(item.getName());
return convertView;
}
The layout for the list rows looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="#+id/fdrowimage"
android:layout_height="35dp" android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:paddingRight="5dp" android:paddingLeft="3dp"/>
<TextView android:id="#+id/fdrowtext"
android:layout_width="wrap_content" android:layout_height="35dp"
android:layout_toRightOf="#+id/fdrowimage"
android:layout_alignTop="#+id/fdrowimage"
android:layout_alignBottom="#+id/fdrowimage"
android:gravity="center_vertical"
android:textSize="23dp"/>
</RelativeLayout>
There are a few things going on here.
First as to the vertical centering of the RelativeLayout. android:gravity="center_vertical" indicates that the children of this view should have center_vertical applied. And it is actually working. As you can see by the size of the green background, your RelativeLayout is only as big as it needs to be to fit the buttons. You have two solutions. If you want the height of the view to stay the same and be centered inside its parent, you would use android:layout_gravity="center". If you want the RelativeLayout to fill the column then you need to set the layout_height of the RelativeLayout to be "fill_parent". android:layout_gravity applies to the view itself inside its parent. android:gravity applies to the view's children.
Second is the layout weight issue. The LinearLayout will first layout any wrap_content items (ie, your RelativeLayout), then it will apply children that have a layout_weight AND a size of 0. If you want your layout_weight to work properly, you need to set the layout_width of the ListView to "0px".
Why when i use SimpleCursorAdapter for ListView i have items height in ListView like this -
(My code based on this)
But when using arrays Listview items have big height
(I learn listview based on this)
Row layout for item listview is
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="#+id/text1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
So My question is why there is a difference in row heights when using ArrayAdapter and SimpleCursorAdapter?
android:textAppearance="?android:attr/textAppearanceLarge"
seemed no effect.
android:minHeight="?android:attr/listPreferredItemHeight"
changed the height for me
The trick for me was not setting the height -- but instead setting the minHeight. This must be applied to the root view of whatever layout your custom adapter is using to render each row.
You need to use padding on the list item layout so space is added on the edges of the item (just increasing the font size won't do that).
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="#+id/text1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp" />
I did something like that :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView textView = (TextView) view.findViewById(android.R.id.text1);
textView.setHeight(30);
textView.setMinimumHeight(30);
/*YOUR CHOICE OF COLOR*/
textView.setTextColor(Color.BLACK);
return view;
}
You must put the both fields textView.setHeight(30);
textView.setMinimumHeight(30); or it won't change anything. For me it worked & i had the same problem.
The height of list view items are adjusted based on its contents. In first image, no content. so height is very minimum. In second image, height is increased based on the size of the text. Because, you specified android:layout_height="wrap_content".
Here is my solutions;
It is my getView() in BaseAdapter subclass:
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView==null)
{
convertView=inflater.inflate(R.layout.list_view, parent,false);
System.out.println("In");
}
convertView.setMinimumHeight(100);
return convertView;
}
Here i have set ListItem's minimum height to 100;
This is my solution(There is a nested LinearLayout):
<?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="fill_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/item"
android:layout_width="match_parent"
android:layout_height="47dp"
android:background="#drawable/box_arrow_top_bg"
android:gravity="center"
android:text="全部收支"
android:textColor="#666"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>