I need to add to add ListView with complicated items background: different for even/odd and rounded corners at the top and bottom. It looks like this:
I have implemented all this stuff via level-list, but there is one more thing I want to do.
Now the bottom item is near the bottom of the screen. It is better to add some space.
I don't want to add bottom margin to ListView, I need margin only for last item.
The ways I see to do this:
Footer
A kind of hack – add footer with empty TextView to ListView. But footers are quite unstable things, they usually disappear after notifyDataSetChanged and there is no way to get them back
Image with transparent pixels
I asked designer to add transparent pixels to bottom background resource. Unfortunately, in this case vertical centering is completely broken.
For example, there is 9patch like this:
And layout like this:
<?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"
>
<!-- View with background with transparent pixels on bottom -->
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="#+id/item"
android:background="#drawable/some_bgr"
android:padding="10dp"
>
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"
android:text="Title"
android:layout_gravity="center"
android:textSize="18sp"
/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Detail"
android:layout_gravity="center"
android:textSize="18sp"
/>
</LinearLayout>
<!-- Just for marking place took by view -->
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_below="#id/item"
android:background="#88ff55"
/>
</RelativeLayout>
The result:
As you see, centering is not working. Unfortunately.
(BTW, if specify this 9patch as background for TextView, centering works good. If you know any article, explaining this, please let me know.)
Add bottom margin to last item in Adapter implementation
That should work, but for unknown reason I still can't get it work.
I don't like this way, because I don't like to modify dimensions in code.
So
There is already imaginary way – construct some XML drawable with particular bitmap and margin. According to drawables concept it should be possible, but I can't find implementation. May be somebody knows?
Any other ideas?
In your ListView, set a paddingBottom and clipToPadding="false".
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="8dp"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"/>
This also works for RecyclerView.
Only use android:scrollbarStyle="outsideOverlay" if you want the scroll bar to not overflow into the padded area.
add an empty footer in your list like this:
TextView empty = new TextView(this);
empty.setHeight(150);
listview.addFooterView(empty);
you can also do it from code if you want, for example here I react to
to EditText different situations:
if(s.toString().length()>0)
{
contacts_lv.setClipToPadding(false);
contacts_lv.setPadding(0,0,0,270*screenDensity);
}
else
{
contacts_lv.setClipToPadding(true);
contacts_lv.setPadding(0,0,0,0);
}
Clocksmith's answer is the best and pretty clever. You can also create an empty footer view.
Add these two lines in your listView XML code:
android:transcriptMode="alwaysScroll"
android:stackFromBottom="true"
Another solution might be that you make a mock view with certain height.
In your adapter in getViewCount return 2.
In getCount return yourData.size+1.
In getViewType check if the element is last element return 2;
Use this type in getView to populate the mockview.
I guess you want to add margin only to last item:
So you can do in this manner, in your getview method the index of the list item and check if its the last item, then progrmatically add margin to the view.
Related
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?
i am designing the app having expected UI like this
i am using RecyclerView with
StaggeredGridLayoutManager manager=new StaggeredGridLayoutManager(3,1);
recyclerView.setLayoutManager(manager);
and this is the row xml file
<?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="wrap_content"
android:layout_marginBottom="#dimen/padding_8dp"
android:layout_marginLeft="#dimen/padding_4dp"
android:layout_marginRight="#dimen/padding_4dp"
>
<com.skcsllp.mutterfly.views.widgets.MfTextView
android:id="#+id/tagName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/textview"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:textSize="#dimen/text_18"
android:background="#drawable/selector_tags"
android:textColor="#color/tags_text_color"
/>
</LinearLayout>
using this much i am getting the output as
i don't want tags to go into second line. i am aware about the fact that i have used the span count as 3 and so getting 3 tags in one line but is there any way to avoid the text wrapping in two lines?
Instead of RecyclerView i would suggest you to use AndroidTagView
need to add dependency
dependencies {
compile 'co.lujun:androidtagview:1.0.3'
}
in your main xml, instead of RecyclerView
<co.lujun.androidtagview.TagContainerLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:padding="10dp"
app:container_enable_drag="false"
app:horizontal_interval="10dp"
app:vertical_interval="10dp"
app:tag_clickable="true"
app:tag_theme="pure_teal" />
and in your activity/fragment
TagContainerLayout mTagContainerLayout = (TagContainerLayout) findViewById(R.id.tagcontainerLayout);
mTagContainerLayout.setTags(List<String> tags);
you will get output something like below, for more you can refer that library, they have given nice example project also.
other usefull libraries are listed below :
https://github.com/loopeer/MultiTextTagView
https://github.com/klinker41/android-chips
https://github.com/ApmeM/android-flowlayout
https://github.com/blazsolar/FlowLayout
I think , you have to write a custom ViewGroup. Using the ViewGroup's onMeasure and onLayout, Get the total width of the screen. Then measure the size of TextView. If the TextView width is less than the screen width, place the TextView. Continue to next TextView, with remaining width. If the TextView width is greater than the remaining screen width, then place the TextView at the next line. Continue this until you placed all the TextViews.
I've to design a UI for an Android app where i've 10 vertical tiles containing image and text(the 2 big boxes in the picture) and on clicking a tile, it disappears and is replaced by scrollable gridview containing 6 elements(shown in the centre of figure below) on the same page. (shown by an animation)
Here is a snapshot of the view I'm trying to explain. This images shows only 2 out of 10 tiles and a gridview which appears on click Each of the white box contains image and text. I'm not good at designing, so a detailed answer of implementing this would be appreciated. Thanks.
There is not much details in your question, even the picture does not clarify everything, but here is a stab at it.
Not sure what you mean when you say the tiles "expand" further, do you expect to see the six tiles in the middle to appear at that time or are they always there? if they appear, would that be animated?
To achieve the picture you have, you should probably get a RelativeLayout at the top level.
That's just because you have this date TextView on the top right and the handle to a SlidingDrawer at the bottom. You can set the background of that RelativeLayout with your wallpaper theme and I guess the blue bar on top if that's static.
Then inside this top-leve RelativeLayout you have a LinearLayout with an horizontal orientation. This one will contain the three "windows" on your picture.
In that horizontal LinearLayout, first you have another LinearLayout with a vertical orientation, then a ViewPager and then another vertical LinearLayout similar to the first one (not sure how the right part is different from the left one or that is supposed to be a complete mirror... ?).
So in summary:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/top_level"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:id="#+id/date_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingTop="..." // fill in some space to offset from the top of the screen
android:paddingRight="..." // same thing to keep it off the right edge
/>
<LinearLayout
android:layout_height="..." // set the height of your content in the center of your screen
android:layout_width="fill_parent"
android:layout_below="#+id/date_text"
android:orientation="horizontal" >
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
<ListView
android:id="#+id/tile_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
<ViewPager
android:id="#+id/pager"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1" // so that will fill the remaining space between the left and the right parts
/>
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
<ListView
android:id="#+id/tile_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
</LinearLayout>
<SlidingDrawer
android:id="#+id/drawer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:handle="#+id/drawer_handle"
android:content="#+id/drawer_contents">
<ImageView
android:id="#+id/drawer_handle"
android:src="#drawable/image for the tab..."
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ImageView>
<Another Layout for the content of the drawer
android:id="#+id/drawer_contents"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
....
</Close that layout>
</SlidingDrawer>
</RelativeLayout>
From there, there is still quite a few things to fill up and some code to write to fill the lists of tiles (on the left and right), handle when the user click on an item, and then also display the content of the ViewPager in the middle of the screen. You'll probably want to use a GridLayout in each page there.
If you need to hide that ViewPager until the user click on some tile, you can set the visibility to hidden and change it in your code.
UPDATE
Now there is more information on how this moves......
OK, so keep the top level RelativeLayout with the date and the SlidingDrawer at the bottom.
In the middle part, you can use the HorizontalListView that was put together by this person: How can I make a horizontal ListView in Android?, the code and instructions and example can be found here: http://www.dev-smart.com/archives/34
Then you need to create your own Adapter to populate that List. You can base it off the BaseAdapter (that decision is more dependent on how your images / information is stored).
In the getView function of that Adapter, can have a layout where both the collapsed and expanded views are combined into one FrameLayout, but only one is visible at a time. It will look like something like this:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent" // assuming the HorizontalListView is set with the right height
>
<LinearLayout
android:id="#+id/collapsed_view"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
</LinearLayout>
<ViewPager
android:id="#+id/expanded_view"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1" // so that will fill the remaining space between the left and the right parts
android:visibility="gone"
/>
</FrameLayout>
In the list adapter, you will need to set proper tags to the different views, so when a user clicks on one image, you know which one was clicked. To expand one view, you change the visibility of the LinearLayout to gone and the one of the ViewPager to visible.
If there should only be only one expanded at a time, you can have a state variable in your Adapter to say which one it is and set the visibility properties correctly for all the views in the list. Then you call invalidate on the ListView to have it refreshed.
There is quite a bit of code to write to do all this, but if you keep it organized, it should not be too bad....
I would like to extend the UI of AutoCompleteTextView. The Functionality is fine, all I need is to add an button to the right that looks like a drop-down button. Sadly AutoCompleteTextView has a 'natural' margin that I can't reduce to 0.
What can I do now?
Dose I have to overwrite onDraw() & onMeasure() to archive my goal (is there an easier way)?
You could put both AutoCompleteTextView and button onto FrameLayout, add some extra margin right to AutoCompleteTextView to make FrameLayout slightly bigger, and align button to parent right. In fact, these 2 views will interfere, but for user they will appear one next to the other w/o any margin.
Another option could be to set custom background to AutoCompleteTextView (probably modified original one taken from Android source with removed margin).
Just remembered that you can supply negative margin. You can put both views onto LinearLayout and set left margin of button to -5dp for example. However, you will still have to supply custom marginless background for button.
you can use RelativeLayout to put Button to the right of AutoCompleteTextView
Sample
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_close_pressed"
android:layout_alignParentRight="true"
android:id="#+id/myBtn"
></Button>
<AutoCompleteTextView android:id="#+id/myautocomplete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:layout_toLeftOf="#+id/myBtn"
/>
</RelativeLayout>
I have a linearlayout which have a textbox(multiline, nearly 5 lines) and image view. Is it possible to draw a image on textview(overlapping)?
Note: I have to specify the coordinates of the image, which are not static, and may be anywhere above text.
Something like this mockup:
I think it can be achieved using RelativeLayout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/Textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="#string/Text2display"
android:textColor="#EEDCAA" />
<ImageView
android:id="#+id/choose_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="-46dp"
android:adjustViewBounds="true"
android:contentDescription="#string/description_logo"
android:src="#drawable/user2" />
</RelativeLayout>
By placing the TextView block above the ImageView, it ensures that the image view overlaps the TextView. Now, based on your requirements and position, use the following commands from the link :-
http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html
You can align left right, top and bottom. Use negative values to navigate the ImageView, if ur using align bottom and stuff.. This will make it to overlap. Please let me know if this was helpful
Is there any specific reason for Linear Layout?
You can do this easily using RelativeLayout . You can have an ImageView overlapping TextView Unless there is a specific reason for using LinearLayout .
If you really (really) need to use LinearLayout, you can subclass TextView and override onDraw to draw your image.
In all your xml files, should define the background color for it, it will solve the problem :
Add this android:background="#android:color/black" in to the View tag you defined.