Display many views efficiently in a FlexboxLayout - android

My goal is to efficiently display a lot of TextViews (with background) in a FlexboxLayout (or something similar).
I want to display information about actors and crew members from a movie in a kind of 'tag'-layout style
How the layout looks like (one of the FlexboxLayouts is marked)
I inflate the TextViews dynamically via LayoutInflater into a FlexboxLayout. The problem is of course that with a lot of data (which means a lot of views, sometimes 30 or more in over 20 Flexbox-Layouts) the creation time of my fragment/activity increases and the activtiy takes longer to open.
The TextView I inflate:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tag_name"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_margin="5dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:gravity="center_vertical"
android:background="#drawable/bg_tag"
android:textColor="?android:textColorSecondary"
android:text="#string/placeholder" />
My container layout (TextViews get inflated into the FlexboxLayout #+id/fxl_names):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<TextView
android:id="#+id/txt_names"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorOnBackground"
android:padding="5dp"
android:textSize="16sp"
android:textStyle="bold"
android:text="test" />
//TextViews get inflated into this FlexboxLayout
<com.google.android.flexbox.FlexboxLayout
android:id="#+id/fxl_names"
app:flexWrap="wrap"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/view_more"
android:visibility="gone"
android:layout_margin="0dp"
android:text="Show all"
style="#style/Widget.MaterialComponents.Button.TextButton.Dialog" />
</LinearLayout>
Thank you for any help/advice on optimizing this layout!

When you had to inflate a lot of views dynamically, you should use something called ViewHolder to ensure the optimization of the inflate view action.
For your problem may you had to use a RecyclerView instead a FlexBoxLayout, the best solution in my opinion. And a FlexBoxLayoutManager to organize your views.
There is a example in the Android FlexBoxLayout repository

Related

Create a clickable item like button with a particuliar view inside

I'm starting in android but I'm working on a project that asks me to do the same thing as the pictures below. However I don't know how to analyze this view to be able to produce something similar.
From what I see in the activity I have a "button" and when I click on it, the elements present in the "button" change. Could someone explain to me how to cut out the view and the elements to do the same thing? Thank you in advance for your answer.
Pictures :
based view
view after click on "button"
I gonna give you a rough idea..
its not a button its a layout containing 2 textviews, 2 imageviews and one seekbar and i will suggest you to use a linearlayout.add a clicklistner on it.
to change the elements after clicking on layout you have to get the references of its elements textview etc as mentioned and change them by yourself. ex- seekbar.setprogress(30) approximately as your picture after click.
xml..
Linearlayout
textview
imageview and textview
imageview
seekbar
\Linearlayout
#Miina Neko Use card view inside cardview use a linear layout (or anyother layout you like) inside cardview use below code i made a layout for you
<androidx.cardview.widget.CardView
app:cardCornerRadius="#dimen/_5sdp"
app:cardElevation="#dimen/_5sdp"
app:cardBackgroundColor="#color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:padding="#dimen/_5sdp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="#drawable/refresh_btn"
android:layout_width="#dimen/_10sdp"
android:layout_height="match_parent" />
<TextView
android:layout_marginLeft="#dimen/_5sdp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="arrrarrr-raaar"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="#dimen/_3sdp"
android:layout_marginBottom="#dimen/_3sdp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_marginRight="#dimen/_5sdp"
android:src="#drawable/refresh_btn"
android:layout_width="#dimen/_10sdp"
android:layout_height="#dimen/_10sdp" />
<ImageView
android:layout_marginLeft="#dimen/_5sdp"
android:src="#drawable/refresh_btn"
android:layout_width="#dimen/_10sdp"
android:layout_height="#dimen/_10sdp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:layout_marginRight="#dimen/_5sdp"
android:layout_marginLeft="#dimen/_5sdp"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateDrawable="#android:drawable/progress_indeterminate_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
NOTE: "#dimen/_sdp" is a library i am sharing link and chage your drawable accrouding to your choice and make ids and in java or kotlin change then programmatically when clicked or any action performed like in second picture hope answer your question..
SDP library link https://github.com/intuit/sdp

What layout elements to use for following type of layout

I am certainly newbie to Andorid Development, and have a knowledge of basic stuff, Relative Layout, Linear Layout, Intent, File Handling etc....
I need to build a project similar to some E-commerce app.
Here's an image of what I want.
How do I achieve the given view of products, as like in blogs or other websites.
Do I have to use List View?
And Please tell what do I have to use to make that "Add Filter Tags" section and how to achieve what I have shown in the picture.
Below is the code which will create skeleton for your UI requirement. You can modify it according to your need.
Your Activity/Fragment xml will look like :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">
<android.support.constraint.ConstraintLayout
android:id="#+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<com.google.android.material.chip.ChipGroup
android:id="#+id/entry_chip_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/cl_parent">
</com.google.android.material.chip.ChipGroup>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/entry_chip_group"
/>
</android.support.constraint.ConstraintLayout>
You Adapter xml for RecyclerView will look like:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="wrap_content">
<ImageView
android:id="#+id/iv_product"
android:layout_width="100dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Name"
app:layout_constraintStart_toEndOf="#id/iv_product"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Information"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_name" />
<TextView
android:id="#+id/tv_more_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="More info"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_info" />
<TextView
android:id="#+id/tv_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Data"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_more_info" />
<TextView
android:id="#+id/tv_tags"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tags"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_data" />
</android.support.constraint.ConstraintLayout>
You should use Chips for your Filter tag. You can add them dynamically to your chip group. Below is the link for reference.
How to use Android Chips
A ListView would be the "default" way. I would also have a look at RecyclerView (a newer incarnation of the same idea). It handles scrolling and recycling the list elements as you scroll, which are all things you don't really want to do on your own.
You'll probably have a separate layout for the individual cards, probably mostly LinearLayouts (horizontal for image -> content, and then a vertical one to hold the content, and maybe a third horizontal one to list the tags).
For the tags, you might want to take a look at Material Design "chips", but honestly that's the part of this mockup that would have me the most concerned. You can make it look however you want, but I'm not sure what your designer means there exactly. Is that a static list of filtering options? Is that on a new page? In a dialog?
EDIT: And as for the top bar, check out the standard App Bar before reinventing the wheel there.
I would definitely go with Recyclerview or this tutorial for your products(images and the product description...) and FrameLayout for the top that includes logo and stuff and finally a regular RelativeLayout for the tags.

left and right alignment rows inside Listview

I want to implement interface like iphone sms:
Now I have chat listview with my custom ChatAdapter, incoming and outcoming messages inflates from different layouts:
outcoming layout:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#drawable/question_bubble"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="27dp"
android:paddingTop="10dp"
android:textColor="#color/BlackColor"
android:textSize="18sp" />
incoming layout:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:autoLink="all"
android:background="#drawable/answer_bubble"
android:paddingLeft="27dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#color/BlackColor"
android:textSize="18sp"/>
I use "layout_gravity", but it doesnt work inside list view. Result:
How can I align question messages to right side?
Add a wrapper layout to your item layouts (for example a LinearLayout) that will have layout_width="match_parent" and gravitiy="left"/"right", this will adjust the inner Layout/TextView to the right position.
In general it is highly recommended to not use wrap_content for items in a ListView, this makes the ListView's onMeasure method to get repeatedly called and slow your app down.
You can try this one:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
**android:layout_width="fill_parent"**
android:layout_height="wrap_content"
**android:gravity="right"**
I've been working on this problem also at the moment. Couldn't get it to work with the suggestions mentioned here. For me it worked only by using:linearlayout.setGravity(Gravity.RIGHT); and setGravity(Gravity.LEFT); programmatically after inflating a standard layout in the getView method of the adapter. These linearlayouts have a width of wrap_content and are child of linearlayout that has match_parent for width. Also don't forget to do this every time a view is being requested via getView, not only if convertView==null.
if you encounter such problem make sure that your text layout is set in this format
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bubble_layout_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/bubble_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/chat_bubble_right">
<TextView
android:id="#+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxEms="12"
android:text="Hi! new message"
android:textColor="#color/colorWhite"
android:textSize="15sp" />
</LinearLayout>
notice that the parent LinearLayout width is set to match_parent while others are set to wrap_content.
this kept me up for hours.

Programmatically add Views inside a (Linear)Layout (that is inside a ScrollView)

I have an app that, after some clicking, shows activity with news contents. I want at a bottom of that to show comments, which are dynamically loaded in async task.
One approach is to use ListView and custom ArrayAdapter, but, i would have to put ListView inside a ScrollView, and it is is a problem, even if i manually override ListView's height. It shows one list item, and one part of the following one.
The other approach is to define LinearLayout as a holder for comments, than inflate another LinearLayouts defined in it's own xml file, populate it's contents, attach to holder's view. It works fine, from program's point of view, except it pushes comments below contents of the news. It's like, it creates another scrollable view of comments underneath contents od news (contents overlap it).
Is there any other way of doing this that has nothing to do with lists, or how can i make the other approach to work.
The relevant code snippet from xml layout that holds news contents is:
<LinearLayout> //global layout
<LinearLayout>
//views that hold title, date, content
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/commentsHolder"
android:orientation="vertical">
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#ed1b24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="KOMENTARI"
android:layout_marginLeft="5dp"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#ed1b24"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="vertical"
android:id="#+id/comments_holder_view"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>
</LinearLayout>
and code that corresponds to one comment is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/comments_holder_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/comment_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/comments_back_details"
android:text="Ovde ide tekst komentara, koji se, naravno, dinamicki dodaje."/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/comment_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/categoryStyle"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" | "
style="#style/categoryStyle"
/>
<TextView
android:id="#+id/comment_pubdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/categoryStyle"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="1dp"
android:orientation="horizontal"
android:layout_margin="5dp"
android:background="#d1d1d1">
</LinearLayout>
Thank you very much for any reply. This is quite important for me.
I am not very sure how you inflate your comments, but here is how I would do it.
Declare the comments Layout as a LinearLayout and give it an id, and then get a reference to that LinearLayout :
LinearLayout commentsLayout=(LinearLayout)findViewById(R.id.commentsLayoutId);
and then just add child Views to this layout :
commentsLayout.addView(newComment);

Android Linear Layout - How to Keep Element At Bottom Of View?

I have a TextView which I want to pin at the bottom of a landscape activity that is using LinearLayout with vertically arranged elements.
I have set android:gravity="bottom" on the text view, but it still likes to be just below the last element of the LinearLayout exactly what I do not want it to do.
Any suggestions?
You will have to expand one of your upper views to fill the remaining space by setting android:layout_weight="1" on it. This will push your last view down to the bottom.
Here is a brief sketch of what I mean:
<LinearLayout android:orientation="vertical">
<View/>
<View android:layout_weight="1"/>
<View/>
<View android:id="#+id/bottom"/>
</LinearLayout>
where each of the child view heights is "wrap_content" and everything else is "fill_parent".
Update: I still get upvotes on this question, which is still the accepted answer and which I think I answered poorly. In the spirit of making sure the best info is out there, I have decided to update this answer.
In modern Android I would use ConstraintLayout to do this. It is more performant and straightforward.
<ConstraintLayout>
<View
android:id="#+id/view1"
...other attributes elided... />
<View
android:id="#id/view2"
app:layout_constraintTop_toBottomOf="#id/view1" />
...other attributes elided... />
...etc for other views that should be aligned top to bottom...
<TextView
app:layout_constraintBottom_toBottomOf="parent" />
If you don't want to use a ConstraintLayout, using a LinearLayout with an expanding view is a straightforward and great way to handle taking up the extra space (see the answer by #Matthew Wills). If you don't want to expand the background of any of the Views above the bottom view, you can add an invisible View to take up the space.
The answer I originally gave works but is inefficient. Inefficiency may not be a big deal for a single top level layout, but it would be a terrible implementation in a ListView or RecyclerView, and there just isn't any reason to do it since there are better ways to do it that are roughly the same level of effort and complexity if not simpler.
Take the TextView out of the LinearLayout, then put the LinearLayout and the TextView inside a RelativeLayout. Add the attribute android:layout_alignParentBottom="true" to the TextView. With all the namespace and other attributes except for the above attribute elided:
<RelativeLayout>
<LinearLayout>
<!-- All your other elements in here -->
</LinearLayout>
<TextView
android:layout_alignParentBottom="true" />
</RelativeLayout>
I think it will be perfect solution:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Other views -->
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!-- Target view below -->
<View
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
Step 1 : Create two view inside a linear layout
Step 2 : First view must set to android:layout_weight="1"
Step 3 : Second view will automatically putted downwards
<LinearLayout
android:id="#+id/botton_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="#+id/btn_health_advice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
You should put the parameter gravity to bottom not in the textview but in the Linear Layout. Like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Something"/>
</LinearLayout>
You can also use
android:layout_gravity="bottom"
for your textview
DO LIKE THIS
<LinearLayout
android:id="#+id/LinearLayouts02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:id="#+id/texts1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="2"
android:text="#string/forgotpass"
android:padding="7dp"
android:gravity="bottom|center_horizontal"
android:paddingLeft="10dp"
android:layout_marginBottom="30dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="50dp"
android:fontFamily="sans-serif-condensed"
android:textColor="#color/colorAccent"
android:textStyle="bold"
android:textSize="16sp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
/>
</LinearLayout>
try this
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewProfileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>

Categories

Resources