I am new to Android, and still learning it. I understood the difference between View and ViewGroup, and also found that a ViewGroup can contain multiple views, but a View cannot contain more Views inside it.
What I want to achieve is something like this:
And what I have right now is just a black box in the background. The XML for the black-box is as follows:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="400dp"
android:layout_height="200dp"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
>
<TextView
android:id="#+id/simpleTextView"
android:layout_width="400dp"
android:layout_height="200dp"
android:background="#drawable/box"
android:text="Sample"
android:textSize="20sp"
android:gravity="center_horizontal"/>
</LinearLayout>
Where I have defined box in a seperate XML.
I just wanted to ask, can anyone please help me in achieving the Final Image above? Especially, what kind of layout should I be using?
You should make your layouts as flat as possible, I mean you should avoid nesting, for that in most cases use ConstraintLayout. You can read about it here: https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout and there are tons of tutorials about that.
It not difficute but we recommend ConstraintLayout
<LinearLayout>//Horizontal
<LinearLayout>//Vertical
<TextView/>
<Button/>
</LinearLayout>
<LinearLayout>//Vertical and add Margin
<Button/>// add Margin
</LinearLayout>
</LinearLayout>
Related
I'm currently developing a library for android and i have a question that I can't find anywhere, is it faster to have different shapes and layouts and calling said layouts according to a method or just have on layout and change the color programmatically?
val d = AppCompatResources.getDrawable(context, R.drawable.success)
inflate(context,message,time, "#4caf50", d!!)
<?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:id="#+id/custom_toast_layout"
android:orientation="horizontal"
android:elevation="4dp"
android:gravity="center_vertical"
android:background="#drawable/pill_custom"
android:padding="5dp">
<ImageView
android:padding="5dp"
android:paddingEnd="0dp"
android:paddingStart="5dp"
android:id="#+id/custom_toast_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:padding="5dp"
android:textColor="#color/white"
android:textSize="16sp"
android:id="#+id/custom_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Color changing is faster, of course. Btw why dont you check it irl? Just make N inflating and N color changing in the test project print timestaps in log (Log.i("tag", String.valueOf(System.currentTimeMillis()));) and calculate the difference.
Inflating a view will use some computing power of the phone so if you are focusing on performance, try to avoid inflating as much as possible.
I don't understand some of the things you have written in the question, but I noticed something about using a lot of layouts, using a lot of layouts increases the work in the main thread, so we have to use the elements directly without adding an extra LinearLayout, ConstraintLayout, etc if possible.
This layout:
<?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="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="90sp"
android:text="5000"
android:id="#+id/textView"
android:layout_gravity="center"
/>
</LinearLayout>
produces the following:
I want to get rid of the top and bottom margin. Where are they coming from in the first place? Maybe for certain letters in certain fonts/languages.
There is already a thread for this question, but none of the answers really work in all situations or the solutions are hacks. There has to be a simple way.
First idea from the thread: android:includeFontPadding="true" (does not change anyting)
Second idea from the thread: android:height="90sp" (removes at least bottom margin)
So, I changed my layout regarding the ideas:
<?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="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="90sp"
android:text="5000"
android:id="#+id/textView"
android:layout_gravity="center"
android:includeFontPadding="true" <!-- idea 1 -->
android:height="90sp" <!-- idea 2 -->
/>
</LinearLayout>
Still it procudes a top margin:
Third idea from the thread: android:layout_marginTop="-12sp"
If add this property it looks at least as desired. But -12sp seems so arbitrary to me. I just adjusted this value via trial and error and I don't like that.
This does not seem like a clean solution to me. This is such a simple thing, I just cannot believe how Android can make it so hard, that you have to use hacks.
Is there a clean solution out there?
Use the below syntax to set text size programmatically and set the required size in dimes file.
textView.setTextSize(getResources().getDimension(R.dimen.textsize));
To set padding use below code based on your needs
yourTextView.setPadding(0, 10, 0, 0);
Set Linearlayout and TextView padding and margins to 0dp. Should work.
Add those to both views:
android:padding="0dp"
android:layout_margin="0dp"
Please refer to example below. I want to have the top layout (below encased in red) to be unmoving in a scrollview in my activity. I have a scrollview as the parent layout and then I thought having a relative layout for the top one would work, and align it to the top, but that didn't really work out as it still remained within the scrollview. I would like to have the users have the red-layout box remain static when they scroll down.
I figure I would also have to put in a topMargin at the top of the scrollview or something in order to fit the redbox layout in.
XML Code posted here: http://pastebin.com/bxdREbeG
Do something like this (hand code, for reference only):
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/YourTopStaticView"
android:layout_width="match_parent"
android:layout_height="48dp"> //Or any other height you want
//Contents of the top view
</RelativeLyout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/YourTopStaticView">
//Contents of the ScrollView
</ScrollView>
</RelativeLayout>
As a side note, do not hardcode children into the ScrollView like that. Use the RecyclerView (which is an updated, modern replacement for ListView), which you will be expected to know how to use if you want to move into serious Android programming. It is actually super easy to use, once you get the hang of it :-)
You should use the ScrollView with only one child (official documentation - http://developer.android.com/reference/android/widget/ScrollView.html). According to your xml, your ScrollView is very complicated with a lot of child widgets.
The best option for you is to use a LinearLayout as the root for the whole container, a LinearLayout( or Relative) for the top layout containing the Reset and Save buttons, and a ListView for the long list that you have. ListView takes care of it's own scrolling. So you don't have to worry about that.
This will improve your code performance as well.
This should suit your needs:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout android:id="#+id/topPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="Multi TTS Implementation"/>
<Button android:id="#+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="SAVE"/>
<Button android:id="#+id/resetAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/save"
android:layout_centerVertical="true"
android:text="RESET ALL"/>
</RelativeLayout>
<ScrollView android:id="#id/scroll"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/topPanel"
android:layout_alignParentBottom="true"
android:padding="5dp">
<!-- Your scrollable content here -->
</ScrollView>
</RelativeLayout>
I have a ScrollView on one of my screens. I want the right edge to have a shadow. I decided the easiest way to do this was to make the child of the ScrollView a RelativeLayout, and have two children of the RelativeLayout -- one being a LinearLayout that will house the layout of the screen, and the second View being the shadow.
Like so...
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- stuff -->
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/shadow"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</ScrollView>
Unfortunately, this doesn't quite work. The ImageView is forcing its dimensions to be the size of the image file. It will not stretch vertically to be the height of the RelativeLayout. I've also tried "match_parent" to no avail. The image is a 9-patch.
Ideas?
Applying drawable content as the source of an ImageView somewhat carries with it an inherent requirement that you want the view to do what it can to accomodate the content without modifying the content itself very much. Typically, this is the behavior you would want out of an ImageView.
What you really want is the behavior you get by setting drawable content as the background of a view, for which you don't really need ImageView at all. A background is designed to simply stretch, fill, etc. to whatever size the view is. Also, since you are using RelativeLayout you can tell the view to match the bound of the view you are shadowing by adding an id and some extra layout_alignparameters.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/content_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- stuff -->
</LinearLayout>
<View
android:layout_width="11dp"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/content_layout"
android:layout_alignBottom="#id/content_layout"
android:background="#drawable/shadow"
/>
</RelativeLayout>
try this
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/ic_launcher"
android:scaleType="fitXY"
android:layout_alignParentRight="true"
/>
here is what I get
and code id
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- stuff -->
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="#drawable/ic_launcher"
android:scaleType="fitXY" />
</RelativeLayout>
</ScrollView>
Your problem has nothing to do with the ImageView or 9-patch itself, but rather with the fact that you're wrapping everything in a ScrollView. A ScrollView will automatically force its children direct child to wrap its content, no matter whether you tell it to FILL_PARENT or MATCH_PARENT - both do exactly the same thing by the way; the only difference is the name, which reflects better the actual behaviour of the flag.
Fortunately ScrollView provides a way to force it to fill the viewport with a flag, which will make the behaviour pretty similar to setting FILL_PARENT to a regular view. Either add the attribute android:fillViewport or use setFillViewport() from code.
Edit: Just to be clear, you need to set that flag on the ScrollView. Also, if it's the ScrollView that should have the shadow, can you not send your 9-patch as background to it? I suppose it does depend on what your actual image looks like. Regarding you comment: yes, the RelativeLayout is flexible in terms of positioning and sizing children, but any child will still be bound to the size of its parent.
I do have the feeling that some of us may be working towards something different than what you have in mind. It would definitely help to clarify things with a simple drawing.
You wanted a Shadow towards the right of your image, Then use single layout with Horizontal Orientation, It's good that you have decide to use Relative Layout. Use
android:orientation="vertical"
inside this layout, add those two images. If you still have a doubt, give me those two images or sample images, i will give you the code
I just need someone to tell me if I understood correctly when to use <include> and when <merge>.
So, I make a header layout which I want to include into some other XML layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Header text" />
</LinearLayout>
And I include it into some other XML this way (which is pretty basic):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
android:id="#+id/header"
layout="#layout/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
This will work well, no issue about it. But in order to optimize the code, I have to use <merge> in the layout which gets included. So the top layout should not have a tag <LinearLayout> but it must look like this:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Header text" />
</merge>
Have I understood this correctly?
From my understanding it will set the merge element as the higher element in the view hierarchy. Include will simply put the whole viewgroup in there. So using your example the view hierarchy should look like:
With merge:
LinearLayout (root)
|
TextView
With include:
LinearLayout (root)
|
LinearLayout
|
TextView
So you will have an extra LinearLayout in the view hierarchy that you do not need. However, sometimes you need that intermediate view. In your case, you wouldn't, since both the LinearLayouts have the same layout params and no other differences.
Yes you understood it correctly. merge is used as pseudo parent element to reduce the number of levels in view trees.
Just check this link, it gives very good explanation of merge.
In your header file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
android:id="#+id/header"
layout="#layout/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout> doesn't make any difference when your file is included in other file you mentioned. So it's a good thing to use merge instead.
Since in XML you must use a single parent element and the rest of the XML elements should be included in it, you should use merge as single parent element and can avoid adding unnecessary parent layout.
Just avoid 'merge' when you want to apply a layout differently than layout is defined in file in which your content is inclded.