text wrapping in two lines - recyclerview - android

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.

Related

Android dynamic views

I have a TextView that displays an error message beside 2 Buttons. They are currently inside a horizontal LinearLayout. The problem is if the TextView is too wide, the 2 Buttons will be pushed off the screen. Is it possible to push the elements downwards in those cases?
If the text is short there are no problems:
(Textview text) (Button1) (Button2)|(Edge of screen)
If the textview is long, I want to push the 2 buttons down a "row"
(Realllllllllllly long text that may|(Edge of screen)
span 2 lines)
(Button1) (Button2)|(Edge of screen)
I think you need to keep one more Linear layout below to your horizontal linear layout and need to check text size runtime if it's width is greater than required two button space then need to hide horizontal linear layout buttons and need to show below layout buttons
to refer how to check text size runtime refer below link :
Refer this link
Try this way: Use FlowLayout
<org.apmem.tools.layouts.FlowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</org.apmem.tools.layouts.FlowLayout>
Inside FlowLayout you can put your view's and it will auto move to next line if not fit.
Yes you can do that, flexbox-layout is the solution.
How to use
Gradle dependency
dependencies {
implementation 'com.google.android:flexbox:0.3.2'
}
And xml code
<com.google.android.flexbox.FlexboxLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexWrap="wrap"
app:alignItems="stretch"
app:alignContent="stretch" >
<TextView
android:id="#+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_alignSelf="flex_end"
/>
</com.google.android.flexbox.FlexboxLayout>
There are few other attributes also [read documentation], which you can try and find what works more suitable in you case.
you can use the TextView predefined method, to gave validation to end user like this
TextView textView=(TextView)findViewById(R.id.text_view);
textView.setError("Your Text is very wide please provide short text");
setError put red mark on textview view, with that we can tell the end user. provided text is wide

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?

Adding bottom margin to ListView last element

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.

What should my Android Layout look like?

I recently asked a question about how to add a view on top of a view, after asking that I realized I needed to added a better layout to my app before proceeding further.
I was reading Android Layout Tricks but noticed it was specifically for text views and image views. I'm looking to do it with two custom views. So I decided to whip up a quick image in paint to hopefully show more clearly of what I'm wanting to do.
This is how I want my layout to split the views. :
This is how it would look with the views drawn. Obviously the purple and blue boundaries would be the background color (greyish). The data above simply displays the y-intercept of the graph drawn with respective color. (So there would be multiple graph views drawn on top of each other)
So my question is, what would my main content view look like? I assume it would have a Linear layout but I'm rather new to these layouts.
EDIT
Using TextViews I'm able to come up with something similar using the following 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">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="Data Placeholder"
android:background="#733674"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="20"/>
<TextView
android:text="Graph Placeholder"
android:background="#374F82"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="80"/>
</LinearLayout>
</LinearLayout>
So The only question that really remains is, am I supposed to use TextViews? Meaning in my Activity am I able to add my custom views where these TextViews are? Or am I supposed to add my custom view to the XML?
Ie.
<DataView
android:text="Data Placeholder"
android:background="#733674"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="20"/>
<GraphView
android:text="Graph Placeholder"
android:background="#374F82"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="80"/>
My custom views are written in Java and I'm not sure how I would let the layout know where the views are located if I was to do it this way.
Try this: http://developer.android.com/resources/tutorials/views/hello-linearlayout.html
It has some very useful information which might help you out in regards to layout_weight as Michell Bak mentioned in the comment.
And here's the page for the Hello Views:
http://developer.android.com/resources/tutorials/views/index.html
Not to be rude, but it would be much better for you to peruse these and learn the xml on your own. That way you can actually understand it and be better able to re-create it later.
I was quite overwhelmed at first with all the code I didn't understand (including xml files), but with a little practice it becomes very easy - just time consuming.
The main thing I'm confused about is what kind of View to put in the
layout. In the examples they use TextView or ImageView, but mine is a
custom view
Well, for your "Custom Data View", you would use a LinearLayout with android:layout_width="fill_parent" and android:layout_height="fill_parent" and android:layout_weight="1" and android:background="#BA4AAB" (See http://www.colorpicker.com/)
Then for your Custom Graph View, I would use:
android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="4" android:background="#7D4ABA"
Note the layout_weight and background values I put are kind of guesses, you might have to tweak them some to match what you want.
The two linearlayouts that I mentioned would be inside one larger LinearLayout with android:orientation="vertical"
Then for the data in the top, you would use 4 text Views, and in code, you'd use setText(...) on those text views to put your data in.
In the xml for textview1, you would add android:id="#+id/textview1" then in code add TextView textview1 = (TextView)findviewbyId(R.id.textview1); then textview1.setText(myString);
For the graph in the bottom part, you would use 2 views for the base of the graph, and set there android:layout_width and android:layout_height to whatever suits you using dip, dp, or px units.
For the lines that you draw, I believe you would have to use the canvas class with a bitmap and call canvas.drawLine(...) (see http://developer.android.com/reference/android/graphics/Canvas.html)

Android horizontal LinearLayout with wrapped text in TextView

I've observed a behavior with layout_weight that I can't explain. The following is a trivial example:
<?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="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="This is a very very very very very very very very very very very very very very very long string."
android:layout_weight="1"
/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:background="#ffffffff"
/>
</LinearLayout>
In a QVGA display, the TextView wraps the text. The white square is displayed to the right of the text.
However, if I remove android:layout_weight="1" from the TextView, the TextView now takes up the entire display width. The white square is no longer displayed.
Why would layout_weight in the TextView affect whether or not the white square is displayed? Shouldn't the View with the white background always be assigned 32dpx32dp first? (It makes no difference if the view were any other types - ImageView or TextView).
The problem I was working on is that I want the white square to always be displayed to the right of the TextView (whether or not the text is wrapped), but I don't want any empty space between the TextView and the white square. (If I add android:layout_weight="1" to the TextView, then there is a gap if the text is not wrapped.)
Any help would be appreciated!
To answer my question #1: One thing I learned by looking at the source for LinearLayout: Not only does layout_weight assign unused space to a child, it also shrinks a child with layout_weight if the child extends beyond the bounds of the LinearLayout. That explains why a TextView with wrapped text is shrunk in my layout.
As for the answer to my question #2, I think you meant android:toRigthOf instead of android:layout_alignRight. Using a RelativeLayout instead of a LinearLayout doesn't change the layout behavior. The tricky part is placing a view immediately to the right of a TextView, without gaps, whether or not the text is wrapped. Setting a maxWidth would limit the TextView's width, but that solution doesn't scale across portrait/landscape and different display dimensions.
Solution - Looks like Dyarish's solution is the best available. My layout problem exists regardless of the layout you use. The key is to set a maxWidth for the TextView so that it doesn't take up the all of the horizontal space in the layout. Because hardcoding a android:maxWidth value in the TextView doesn't scale across different displays, setting the maxWidth at runtime, as Dyarish suggested, is a good solution.
Hopefully this is what you are looking for.
First off, here is a great resource I found for Creating UI's.
layout_weight - Specifies how much of the extra space in the layout to be allocated to the View.
If you want to ensure that the white square is always to the right of the textview, you can use a Relative View, and add the parameter to the view. android:layout_alignRight="+id#yourTextViewID". This should always make the box appear right beside the textView area. You should probably also add something like android:maxWidth="250px" This will ensure that you don't push the white box completely out of the screen.
Here is a code sample:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:maxWidth="250px"
android:id="#+id/TextForWhiteBox"
android:layout_height="wrap_content"
android:layout_gravity="center|left"
android:text="This is a very very very very very very very very very very very very very very very long string."
/>
<View android:background="#ffffffff" android:layout_width="32dp" android:layout_height="32dp" android:id="#+id/view1" android:layout_toRightOf="#+id/TextForWhiteBox"></View>
</RelativeLayout>
You could also add to the View:
android:layout_alignTop="#+id/TextForWhiteBox" android:layout_alignBottom="#+id/TextForWhiteBox"
to make the white box the same size as the TextView.
Firstly I've tested the code from my other answer and it does exactly what you've described you've wanted. (unless I'm misunderstanding what you are asking for). You definitely do not want to use the android:layout_alignRight which is not what is in the code sample. That would simply keep the box on the right hand of the screen and not be affected by the textview at all. This sample uses android:layout_toRightOf="#+id/TextForWhiteBox" which is possible due to it being a relative layout. Since the Relative Layout allows you to place objects in relation to others. That line will always place the box just to the right of the textview with no gaps.
As for the screen orientation changes:
When the orientation changes it creates a new instance of the view.
Here is a simple solution.
//Add to oncreate in your Activity
private TextView textStatus;
textStatus = (TextView) findViewById(R.id.TextForWhiteBox);
// This get's the width of your display.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
// Now you know the screen orientation, and it's width. So just set the maxwidth of the text view to match the display width - the pixels of your white box.
textStatus.setMaxWidth(width - 32); // 32 is here because you already know the size of the white box. More logic is needed to dynamically get this value, because you would need to wait for the activity to be fully created.
}
Here is the main.xml I used:
<?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="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:id="#+id/TextForWhiteBox"
android:layout_height="wrap_content"
android:layout_gravity="center|left"
android:text="This is a very very very very very very very very very very very very very very very very very very very long string."
/>
<View android:background="#ffffffff" android:layout_width="32px" android:layout_height="32px" android:id="#+id/view1" android:layout_toRightOf="#+id/TextForWhiteBox"></View>
</RelativeLayout>
You might need some additional logic to keep screen values.
This code has been tested, you should be able to literally copy and paste this to work as you asked.
Also depending on your logic you could use something like this to return the screen orientation.
int orient = getResources().getConfiguration().orientation;
Hope this helps!
If this helped you, please click the accepted button. =) Cheers!

Categories

Resources