I have a ListView inside a HorizontalScrollView, the scrollbartrack takes up a area to the right. When I change to Scrollbarstyle:insideOverlay it doesn't it still takes up the are. If I change to scrollbars:none the area disappears so I know it has something to do with the scrollbars.
I have tested with all styles on scrollbars and played around with padding and margin haven't found any way to get it to actually overlay. It seems to be the HorizontalScrollView that creates the problem if I remove that the scrollbars are overlayed correctly.
In this code I set the overlay both in xml and code but none of them seems to work.
Here is a basic working example where the problem shows up. In my real code the layout is not just green so a solution with coloring the track green wont work.
public class ScrollTest extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_test);
ListView lv= getListView();
lv.setDivider(null);
//Just to make sure!
lv.setScrollBarStyle(ListView.SCROLLBARS_INSIDE_OVERLAY);
// create the grid item mapping
String[] from = new String[] {"rowid", "col_1", "col_2", "col_3", "col_4", "col_5"};
int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4, R.id.item5 , R.id.item6};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 50; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
map.put("col_4", "col_4_item_" + i);
map.put("col_5", "col_5_item_" + i);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.row, from, to);
lv.setAdapter(adapter);
}
}
And the relevant xml for the layout.
activty_scroll_test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbarStyle="insideOverlay"/>
</HorizontalScrollView>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:background="#android:color/holo_green_dark"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/item1"
android:text="row_id"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="40dip"
android:padding="5dp"
/>
<TextView android:id="#+id/item2"
android:text="col_1"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="100dip"
android:padding="5dp"
/>
<TextView android:id="#+id/item3"
android:text="col_2"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="100dip"
android:padding="5dp"
/>
<TextView android:id="#+id/item4"
android:text="col_3"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="100dip"
android:padding="5dp"
/>
<TextView android:id="#+id/item5"
android:text="col_4"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="100dip"
android:padding="5dp"
/>
<TextView android:id="#+id/item6"
android:text="col_5"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:width="100dip"
android:padding="5dp"
/>
</LinearLayout>
From android:scrollbarStyle (admittedly not the best documentation in Android):
When inset, they add to the padding of the view. [..] If you want them to appear at the edge of the view, ignoring the padding, then you can use outsideOverlay or outsideInset.
So, setting it to insideOverlay, with no padding on the ListView and no margins on the list items, you would get a scrollbar on top of the list items.
You can use Hierarchy Viewer to figure out where the spacing is coming from. It's likely padding or margins on the list items, namely that 5dp on #+id/item6.
Related
I have a list view that needs to support being navigable via a bluetooth keyboard. The list view also has a header view that needs to be navigable via the keyboard. The problem is when I press the down arrow, the focus is directed to a view above the list, in this example #+id/header . I need to press down as many times as there are list items for the focus to move to the list instead of going back and forth between the header and the list view's header...It's rather strange.
I've made a sample app to try and narrow the problem down to no avail. It's also worth noting if #+id/header is not focusable (for example when I made it a text view), the keyboard works as expected which, unfortunately, is not an option for me because my header needs to support bluetooth navigation.
Any help would be amazing, thanks.
MainActivity.java
package com.example.listviewtest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private SimpleAdapter adapter;
private List<HashMap<String, String>> data;
private MyListView list;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView) findViewById(R.id.listview);
TextView empty = (TextView) findViewById(R.id.empty);
// create the grid item mapping
String[] from = new String[] {"rowid"};
int[] to = new int[] { R.id.item1};
// prepare the list of all records
data = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
data.add(map);
}
// fill in the grid_item layout
adapter = new SimpleAdapter(this, data, R.layout.grid_item, from, to);
list.addHeaderView(getLayoutInflater().inflate(R.layout.grid_header, null));
list.setEmptyView(empty);
list.setItemsCanFocus(true);
list.setAdapter(adapter);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<Button
android:id="#+id/header"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Header"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.DialogWindowTitle"
android:padding="20dp"
android:layout_marginBottom="20dp"
android:onClick="toggleList"
android:clickable="true"
/>
<!-- ListView (grid_items) -->
<ListView android:id="#+id/listview"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />
<TextView
android:id="#+id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm empty"
android:gravity="center"
android:visibility="gone"/>
</LinearLayout>
grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="20dp" />
grid_header.xml
<?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="horizontal"
android:focusable="false"
style="?android:attr/buttonBarButtonStyle">
<TextView android:id="#+id/item1"
android:text="button1"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:layout_weight="1"
android:width="0dp"
android:height="30dip"
style="?android:attr/buttonBarButtonStyle" />
<TextView android:id="#+id/item2"
android:text="button2"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:layout_weight="1"
android:width="0dp"
android:height="30dip"
style="?android:attr/buttonBarButtonStyle" />
</LinearLayout>
In my listview there is a checkbox, textviews and an imageview. When I click on an item, the onclicklistnere is not working. I know this is because the checkbox has its own listener and it overrides the listview onclicklistener. Fine. When I set
android:focusable="false"
android:focusableInTouchMode="false"
in the checkbox, I can click on the list item but the checkbox becames orange as well (like the item).
So this is a half solution, does anyone know a better one?
This is the class:
public class ListViewTutorial2Activity extends Activity {
SimpleAdapter mSchedule;
ListView list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView) findViewById(R.id.SCHEDULE);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
map.put("train", "101");
map.put("from", "6:30 AM");
map.put("to", "7:40 AM");
mylist.add(map);
map = new HashMap<String, String>();
map.put("train", "103(x)");
map.put("from", "6:35 AM");
map.put("to", "7:45 AM");
mylist.add(map);
mSchedule = new SimpleAdapter(this, mylist, R.layout.row,
new String[] {"train", "from", "to"}, new int[] {R.id.TRAIN_CELL, R.id.FROM_CELL, R.id.TO_CELL});
list.setAdapter(mSchedule);
list.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = list.getItemAtPosition(position);
}
});
}
}
and row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="4dip"
android:paddingBottom="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="#+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:descendantFocusability="beforeDescendants">
</CheckBox>
<TextView android:id="#+id/TRAIN_CELL"
android:layout_width="50dip"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/FROM_CELL"
android:layout_width="70dip"
android:layout_height="wrap_content" android:layout_weight="1"/>
<TextView android:id="#+id/TO_CELL"
android:layout_width="60dip"
android:layout_height="wrap_content" android:layout_weight="1"/>
<ImageView
android:id="#+id/icon"
android:layout_width="22px"
android:layout_height="22px"
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="#drawable/icon" >
</ImageView>
</LinearLayout>
Have you tried adding this to your CheckBox in your xml layout?
android:focusable="false"
android:focusableInTouchMode="false"
This worked for me and might be a better solution then what you had to go through.
You don't need to set any special properties on the CheckBox to do this. In the ListView, however, try the following:
android:clickable="true"
android:descendantFocusability="beforeDescendants"
If that doesn't work, you're probably doing something wrong elsewhere.
android:focusable="false"
It will solve the problem in this context
I meet this problem at RecyclerView, maybe this answer will be useful for somebody.
All of these answers don't helped me. Maybe this solutions isn't optimal, but here it is:
<FrameLayout
android:id="#+id/like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/views_holder"
android:layout_toEndOf="#+id/btn_comment"
android:clickable="true">
<CheckBox
android:id="#+id/cb_like"
android:layout_width="wrap_content"
android:layout_height="#dimen/pressable_size"
android:gravity="center_vertical"
android:button="#drawable/ic_heart_checkbox"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
tools:text="324"
/>
</FrameLayout>
I have added ViewGroup wrapper (in this case - FrameLayout) - and set click listener to FrameLayout:
(In my case with ButterKnife):
#OnClick(R.id.like)
void onLikeClicked() {
cbLike.setChecked(!cbLike.isChecked());
if (onNewsClickListener != null) {
onNewsClickListener.onLikeClicked(getAdapterPosition());
}
}
R.id.like - FrameLayout, cbLike(CheckBox).
It works correctly.
I had the same problema even when i add this to the checkbox
android:clickable="false"
android:focusableInTouchMode="false"
android:focusable="false
Then I realized that my problem it was because i had a onStateChangedListener for the checkbox
I currently have a tabview with a listview inside. I only have three items in the listview and for some reason there is a bunch of white space at top. That is, the first item doesn't start at the top but rather in the middle. Any ideas? Also, i'm thinking that I am using the wrong layout. anything better than a listview if i only need to display three items? Thanks.
Code:
// Data to put in the ListAdapter
private String[] sdrPlaylistNames = new String[]{ "More Playlists...","Dubstep", "House"};
Intent playbackServiceIntentDUB, playbackServiceIntentHOUSE;
//alert dialog
AlertDialog.Builder builder;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlists_layout);
//fill the screen with the list adapter
playlistFillData();
playbackServiceIntentDUB = new Intent(this, DUBAudioService.class);
playbackServiceIntentHOUSE = new Intent(this, HOUSEAudioService.class);
}
public void playlistFillData() {
//create and set up the Array adapter for the list view
ArrayAdapter<?> sdrListAdapter = new ArrayAdapter<Object>(this, R.layout.list_item, sdrPlaylistNames);
setListAdapter(sdrListAdapter);
}
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" >
<ListView
android:id="#id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/selectP" android:stackFromBottom="false">
</ListView>
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp" />
<TextView
android:id="#+id/selectP"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="Select A Playlist Above"
android:textColor="#FF3300"
android:textSize="22dp"
android:textStyle="bold" >
</TextView>
</RelativeLayout>
If you want to display only three items then I think you have to use TableLayout.
Android - Table Layout.
Oh I missed your real problem in my previous answer.
Simply set android:layout_alignParentTop="true" to your list view as
<ListView
android:id="#id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_above="#+id/selectP" android:stackFromBottom="false">
</ListView>
Hope this time I am clear..
Set your list view to AlignParentTop = true
I have a listview and two textveiws in it for two columns. My goal is to set the colour of e.g. the 5th row of the listview to blue. Details:
config.xml has the layout for the acitivty: buttons and the listview. Part of it:
<ListView android:id="#+id/ListView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/TextView01">
</ListView>
row.xml defines the two coloumns for the listview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="4dip"
android:paddingBottom="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/linlay0">
<LinearLayout android:orientation="horizontal"
android:id="#+id/linlay"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/left"
android:layout_width="160px"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:paddingLeft="5px"/>
<TextView android:id="#+id/right"
android:layout_width="140px"
android:layout_height="wrap_content"
android:maxWidth="140px"
android:singleLine="false"/>
</LinearLayout>
</LinearLayout>
MainActivity.java is for the management for the activity, as well as the listview. So contentview is set to config.xml:setContentView(R.layout.config);
This is how i upload the listview with data:
lv1=(ListView)findViewById(R.id.ListView01);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
for (int i=0; i<31; i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("left1", date[i]);
map.put("right1", name[i]);
mylist.add(map);
}
simpleAdapter = new SimpleAdapter(this, mylist, R.layout.row,
new String[] {"left1", "right1"}, new int[] {R.id.left, R.id.right});
lv1.setAdapter(simpleAdapter);
date[i] and name[i] are arrays declared and uploaded at the beginning of the class.
I am running some queries, comparing arrays and now i want to the set colour of a specific row in the ListView to blue. Like i said contentview is set to config.xml, while the TextViews of the ListView is in row.xml.
So TextView txt1 = (TextView) findViewById(R.id.left); is uninterpretable for Eclipse.
I would have solved this by implemented my own adapter, and used the position parameter in the getView() method of the adapter to set the background of the LinearLayout by code.
In your CustomAdapter in getView method use this
if(position==5)
{
convertView.setBackgroundColor(Color.BLUE);
}
simpleAdapter is a system adpater,you can not control it.In my opioion,if you want set color at 5th row,you should implementation any adapter and override the getView or bindView method
,accord the position(row number) you can do anything you want
I'm just starting to develop on Android so this may be a very basic thing, but. . .
I'm having a really hard time setting up a ListView within a LinearLayout. Maybe it's a problem in my XML layout, or maybe it's a problem with my databinding code.
I'm confused by the many tutorials that say that my Activity should extend ListActivity. Why would this one widget require that my entire UI be changed?
The thing is, I only want the scrolling box of items to occupy a part of this one screen. Is ListView the wrong widget to use? Should I be using a ScrollView instead?
Thanks -- here's my XML:
<?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"
android:background="#FFF"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/enter_text"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<EditText
android:id="#+id/txtTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_weight="1"
android:width="200px"/>
</LinearLayout>
<ListView android:id="#+id/listRecent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
And here's my code:
public class MyApp extends Activity {
private String TAG = "MyApp";
//UI ELEMENTS
EditText txtTo;
ListView listRecent;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//GET REFERENCES TO UI ELEMENTS
listRecent = (ListView) this.findViewById(R.id.listRecent);
try {
//----------------------------------------
// create the grid item mapping
String[] from = new String[] {"zero", "one", "two", "three"};
int[] to = new int[] {0, 1, 2, 3};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.recently_dingdonged, from, to);
listRecent.setAdapter(adapter);
//----------------------------------------
}
catch(Exception e) {
Log.e(TAG, "Error here (3116019)", e);
}
}
ListView should be nested inside of scrollview. By extending listActivity you gain the ability to setAdapter and populate the data into your list view through the main object and not through instantiating the list. This is by no means a requirement though.
You don't need to make your Activity extend ListActivity. You can, but it's not necessary.
In relation with your xml, try this out:
<?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"
android:background="#FFF"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/enter_text"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/txtTo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_weight="0.5"
android:width="200px"/>
</LinearLayout>
<ListView android:id="#+id/listRecent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
</LinearLayout>