Aligning listview items using code android - android

I have a listview.
The list items must be populated using code and in the following pattern
The odd numbered list items must be placed aligned with the left side of the screen.
The even numbered list items must be place aligned with the right side of the screen.
The width must depend on the size of the content.
These task must be performed using code.
<LinearLayout android:id="#+id/list_item"
android:paddingLeft="5dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
<TextView android:id="#+id/text_view"
android:autoLink="all"
android:paddingTop="6dip"
android:paddingBottom="3dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:linksClickable="false"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#ff000000"
android:textSize="18sp" />
</LinearLayout>
note:i use cursor adapter to bind the data with listview

You must see Google I/O 2010 - The world of ListView to understand how ListView works.
For your situation in getView(...) method of your list adapter you could add something like this:
if(position%2==0){
//even
convertView.setGravity(Gravity.RIGHT);
} else{
//odd
convertView.setGravity(Gravity.LEFT);
}
In order to set width dependency on content change all "layout_width properties" to "wrap_content" in your xml above.
Also it would be useful to read ListView Tips & Tricks post series.
Hope I've got the question correctly.

Related

Setting up layout for timetable

I have a list of timetable-events and would like to lay them out as in the image.
You can ignore the backgroundgrid as I will not use one.
Every event in the timetable has a start- and endtime. The height of the item in the view is related to the duration of the event. The list is observed with LiveData so changes to the timetable need to update the screen.
I considered the following approaches:
a) Using a recyclerView. Unfortunatly this either lays out the items from left to right and scrolls vertically or lays them out vertically but scrolls horizontally. I basicly need vertical layout, jumping to the next column when necessary with vertical scrolling.
b) using a gridlayout (not gridview) and spanning items over rows. Drawback is that all items need to be a multiple of a single row. This assumes all events have a duration which is a multiple of a minimum time. I can use 1 or 5 minutes as that minimum duration, but it would result in a lot of rows. Furthermore I am not sure about updating the screen, the scrolling and if this is memory efficient.
c) using a parent scroll-layout with five vertical lineairlayouts. Programmatically adding the items to the corresponding lineairlayout with the right heigth. This adds all the viewitems to the layout even if they are not visible on screen. I can forget about LiveData updates I guess.
Is there another option I have overlooked? Or can I use a recyclerView anyway? How do I do that?
P.S. I am still using Java but started to learn Kotlin
You can use Android Week View
Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling.
Features
Week view calendar
Day view calendar
Custom styling
Horizontal and vertical scrolling
Infinite horizontal scrolling
Live preview of custom styling in xml preview window
Add below dependencies
implementation 'com.github.alamkanak:android-week-view:1.2.6'
WeekView in your xml layout.
<com.alamkanak.weekview.WeekView
android:id="#+id/weekView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:eventTextColor="#android:color/white"
app:textSize="12sp"
app:hourHeight="60dp"
app:headerColumnPadding="8dp"
app:headerColumnTextColor="#8f000000"
app:headerRowPadding="12dp"
app:columnGap="8dp"
app:noOfVisibleDays="3"
app:headerRowBackgroundColor="#ffefefef"
app:dayBackgroundColor="#05000000"
app:todayBackgroundColor="#1848adff"
app:headerColumnBackground="#ffffffff"/>
You can use tableLayout.
Example -
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="*" android:stretchColumns="*"
android:background="#ffffff">
<TableRow
android:id="#+id/tableRow1"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView
android:id="#+id/TextView04"
android:text="Row 2 column 1"
android:layout_weight="1" android:background="#dcdcdc"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
<TextView
android:id="#+id/TextView04"
android:text="Row 2 column 2"
android:layout_weight="1" android:background="#d3d3d3"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
<TextView
android:id="#+id/TextView04"
android:text="Row 2 column 3"
android:layout_weight="1" android:background="#cac9c9"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
</TableRow>
For tutorials refer-
https://androidexample.com/Table_Layout_-_Android_Example/index.php?view=article_discription&aid=74
May be you can achieve this using FlexboxLayout.
Google flexbox-layout
I did not find an appropiate library or layout so I ended up writing my own view, calculating in onDraw the position of every appointment. It was not as hard as it sounds.

Android ListView width keeps changing

Firstly, I am new to android so if I have missed something basic I apologise.
I have a page which has two ListViews side by side, both with varying amounts of content. I also have a TextView above the ListViews and another TextView below the listviews. These text view boxes change based on items selected in either of the two ListViews.
These two ListViews sit side by side, taking up half of the screen each, while a Textview sits directly above and directly below, both centred to the page. An image is shown below.
This is the page looking normal on load.
The problem is when I select an item from either list. I have a feeling I am missing some XML properties, but I am not sure which properties or if this is even the case. When an item is selected, let's say from the ListView on the right, the TextView at the bottom is updated with text taken from an array. The ListView also decides to change the width and I am not sure why this is.... I don't want the ListView to change width. I want it to remain taking up half of the page and half of the page only.
This is the page after an item from the right ListView has been selected.
I would also like to keep things in RelativeLayout. I also believe it is only an XML issue and not to do with the adapter or any other code so I will not include that for now. I can include it if required.
Any help would be great. Thanks in advance.
content_titles.xml my activity xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TitlesActivity">
<ListView
android:id="#+id/unlocked_titles_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:longClickable="true"
android:layout_below="#+id/current_title"
android:layout_alignEnd="#+id/requirements"
android:layout_marginEnd="26dp"
android:layout_above="#+id/requirements">
</ListView>
<TextView
android:id="#+id/current_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="65dp"
android:text="Current Title: Novice"
android:textSize="24sp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<ListView
android:id="#+id/locked_titles_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignStart="#+id/requirements"
android:layout_marginStart="28dp"
android:layout_above="#+id/requirements"
android:layout_below="#+id/current_title"/>
<TextView
android:id="#+id/requirements"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="34dp"
android:text="temp"
android:textAlignment="center"
android:textSize="24sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
activity_listview.xml used as the individual rows of the ListViews
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" >
</TextView>
The problems with layout could be caused by ScrollView to be the wrapper
I stumbled upon some note in http://developer.android.com/reference/android/widget/ExpandableListView.html
"...Note: You cannot use the value wrap_content for the android:layout_height attribute of a ExpandableListView in XML if the parent's size is also not strictly specified (for example, if the parent were ScrollView you could not specify wrap_content since it also can be any length. However, you can use wrap_content if the ExpandableListView parent has a specific size, such as 100 pixels."
I removed wrapping ScrollView and linear layout started working properly. Now its only to understand how to wrap the stuff to ScrollView. God help me
But anyway this is really weird behavior. I think that fill_parent is not really correct wording. When using heirarchyviewer tool I always see WRAP_CONTENT and MATCH_PARENT values for layout_width and leayout_height. So probably fill_parent is actually means match_parent which puts me in cognitive dissonance.
You have your layout_width properties set to wrap_content. This means that they could change as the data changes. I would recommend putting your ListViews in a LinearLayout with orientation:horizontal and set the amount of space that each element takes up with layout_weight. Here is a relevant SO question What does android:layout_weight mean?

Android ListView: how to add various itens in a row in a dynamic way?

I want some tips in how to complete one task.
We got three EditTexts, a button and a llistview.
The idea here is when the button is pressed, the texts from the three EditTexts will be show in a listview, side by side, giving the impression that we got a table here.
The problem here is I don't know how to do it. I've tried to search something on the net, but I just got nothing.
I'd really appreciate if you could help.
Thaks for the attention and have a nice day.
There are a couple ways to achieve what you want. If I'm understanding correctly you have a listview and a button. When you click the button, you want 3 editTexts to appear in your listview side by side so that it looks like a table.
The simplest solution is have your list item layout, inflated in your listadapter, simply be a linearlayout with weightSum="3" containing 3 edittexts with layout_weight="1" and layout_width="0dp"
so your list_item.xml would look something like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3">
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
</LinearLayout>
Then, in the onClick for your button, iterate through the children of the list row and set the visibilities to visible.
As for adding rows dynamically, use a listadapter and a collection and use the notifydatasetchanged to update the list when your collection gains/loses items.

Limit number of rows of listview

I am developing an application that needs to pair with other devices through Bluetooth. I was having trouble in order to show the list of paired devices in correct manner. I had also viewed the example in the android api (Bluetooth Chat), but i was having the same problem.
The list of paired devices are to big and then hides a search button that are at the bottom of the list.
My xml code is very the same of the example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="#+id/listpaired_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/title_paired_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="#+id/paired_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="1"
/>
<TextView android:id="#+id/list_new_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/title_other_devices"
android:visibility="gone"
/>
<ListView android:id="#+id/new_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="2"
/>
<Button android:id="#+id/btscan"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btscan"
/>
</LinearLayout>
But and i can't show the search button at the bottom.
Here my screen:
My Screen
You could see a bit of the button at the bottom of the dialog window.
It's possible to limit the number of rows shown at the listview ? Can anyone tell me how i can fix this problem
Firstly some points about your code:
layout_weight is only meaningful if an object has no size in a certain dimension, that is you set layout_height or layout_width to 0, so this has no effect on your code.
Setting the height of a ListView to wrap_content is pretty meaningless, and even if it works it's bad practice. Use either 'fill_parent' or a definite height.
The button is hidden because, as per the point above, the ListViews you have created have no predefined size so take up as much space as they can, pushing the button off the screen.
So let's think about what you really have there - it's just a single list with a button at the bottom (yes you may have headers or multiple sources of data in there but we'll get onto that).
The following layout will give you a ListView at the top and a Button at the bottom. The ListView will take up any space not being used by the Button. Notice how the Button is defined before the ListView in the layout - this causes Android to calculate how much height the button takes up before considering the ListView. It then gives the ListView the rest of the height available.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="#+id/btscan"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/btscan"
/>
<ListView android:id="#+id/all_devices"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/btscan"
android:stackFromBottom="true"
/>
</RelativeLayout>
So that's the layout. Now lets consider the actual content of your list: you have a header, followed by a list of paired devices, followed by another header and then a list of new devices.
You can create this using a single Adapter - Commonsware provides a very good implementation called MergeAdapter but you could code your own. MergeAdapter doesn't directly let you a view (e.g. for the headers) but thankfully Commonsware also provides the SackOfViewsAdapter which allows you to add views to it, and then you can add the SackOfViewsAdapter to the MergeAdapter.
Here is some pseudo-code which should accomplish what is outlined above.
// This is the adapter we will use for our list with ListView.setAdapter
MergeAdapter listAdapter = new MergeAdapter();
// The first header - you'll need to inflate the actual View (myHeaderView1) from some resource
// using LayoutInflater
List<View> firstHeaderViews = new List<View();
firstHeaderViews.add(myHeaderView1);
SackOfViewsAdapter firstHeaderAdapter = new SackOfViewsAdapter(firstHeaderViews)
// Second header
List<View> secondHeaderViews = new List<View();
secondHeaderViews.add(myHeaderView2);
SackOfViewsAdapter secondHeaderAdapter = new SackOfViewsAdapter(secondHeaderViews);
// Now to add everything to the MergeAdapter
// First goes the first header
listAdapter.addAdapter(firstHeaderAdapter);
// Now your first list
listAdapter.addAdapter(firstListAdapter);
// Now your second header
listAdapter.addAdapter(secondHeaderAdapter);
// Now your second list
listAdapter.addAdapter(secondListAdapter);
// Now set the adapter to the list
myList.setAdapter(listAdapter)
The layout produced should look something like this. Note I extended the list to show how it behaves with a list longer than the screen; the button still remains visible. The red box marks the bounds of the screen.
You can limit the number of rows shown at the list view, but not sure if that will really help you in what you want to achieve, because you're hiding information from the user that might be important to him. You can limit the number of rows by limiting the number of items you pass to the listview adapter, or you can set the visibility to 'gone' in the getView method when the list view reaches a certain position (you can check the 'position' parameter of getView()).
However, I would suggest you use only one list view (add a separator for the 'new/other devices' title into the view for a list item, but hide it by default, and then, as already suggested by suri, use headers and footers for the listview (to place the scan button).

Set ListView Scrollable

When I do a ListActivity my ListView works correctly : I can scroll by dragging with the TouchScreen or with the Mouse Wheel.
However when I incorporate a ListView in a layout (with buttons, textview, linearLayouts, ect... ) I can't scroll it by dragging, I can just scroll with the mouse wheel.
How can I enable the "touch" scroll of a listView (outside a list activity) ?
Try adding android:isScrollContainer="true" to your ListView definition. That ought to do it.
Another couple points of advice:
You can have the ListView automatically show the "Not found" TextView by using ListView.setEmptyView()
You should use dip or pt for your fonts, not sp. Try your app out on 3 different AVDs, one with a QVGA skin, one with HVGA, and one with WVGA, and I think you'll see what I mean. I would recommend pt except for the fact that the Droid has a glaring bug which causes font points to be incorrectly scaled. Try dips instead.
<LinearLayout
android:id="#+id/results_panel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/panel_background"
android:orientation="vertical"
android:layout_marginTop="10dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginBottom="10dip"
android:visibility="invisible">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/results"
android:textSize="18sp"
android:textStyle="bold"
android:shadowColor="#7299e1"
android:shadowRadius="2.0"
android:shadowDx="3"
android:shadowDy="2"
android:gravity="center"/>
<TextView
android:id="#+id/results_panel_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/not_found"
android:textSize="18sp"
android:gravity="center"/>
<ListView
android:id="#+id/results_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#0000"
android:background="#0000"
android:layout_weight="0.5"/>
</LinearLayout>
The first linear layout Visibility is set programmaticaly to visible (so don't worry about that;)).
The first TextView is a title which appear above the ListView.
The second TextView Visibility is set to visible if I have no item otherwise to gone.
The ListView display the items and is set to visible if I have items otherwise to gone.
The items are Strings in a string Array displayed with an Array adapter.
Eventually I've found out ! Sorry it's entirely my fault : my layout is really complex and I've shown you the part containing the listView but I had forgotten that my whole screen was embedded in a scrollview. And so there was a conflict between this listView and the ScrollView parent.
Excuse me again and thank you for your answers and advises !

Categories

Resources