Align TextViews in specific way - android

I am currently learning some techniques in Android and I would like to add TextViews via button press (via Java) into the app (View). But before they get added through code I want to attach to each TextView a self made preconfigurartion style from "res/values/styles.xml". That is the main idea so far.
Basically I would like to know how to configure my TextViews (in styles.xml) and the given Layout (e.g. main_activity.xml) in the XML file of an Activity in such a way so they look like in this picture:
So the goal is to preconfigure the Layout and TextView in such a way, that I only have to add the TextViews one after another so that they align themselfes in the way like in the picture.
What do I have to do exactly in order to achieve this?
// main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView style="#style/AddedTextView" />
</RelativeLayout>
...
<Button
android:id="#+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
// res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AddedTextView" parent="Widget.AppCompat.TextView">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#drawable/custom_textview_design</item>
<item name="android:text">TestTV</item>
<item name="android:textColor">#color/common_text_color</item>
<item name="android:textSize">7pt</item>
<item name="android:layout_alignParentLeft">true</item>
</style>
</resources>

You can apply the style programmatically using a ContextThemeWrapper:
val textView = TextView(ContextThemeWrapper(this, R.style.AddedTextView))
And to add TextViews connected to one another and wrap them vertically, you can use the Google's FlexBoxLayout
Here's the basic layout:
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/flexLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexDirection="row"
app:flexWrap="wrap">
</com.google.android.flexbox.FlexboxLayout>
And adding the views programmatically is very straightforward:
val flexboxLayout = findViewById<View>(R.id.flexLayout) as FlexboxLayout
for (i in 1..50) {
val textView = TextView(ContextThemeWrapper(this, R.style.AddedTextView))
val layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
layoutParams.rightMargin = 40
textView.layoutParams = layoutParams
textView.text = "TextView $i"
flexboxLayout.addView(textView)
}

Related

CardView with different corner radius

I have the following CardView and I want to set different radius for each corner in the card. Is it possible to change them by XML or programmaticaly? Thanks in advance.
<android.support.v7.widget.CardView
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"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
app:cardCornerRadius="0dp"
app:cardElevation="0dp">
</android.support.v7.widget.CardView>
EDIT
As Avinash suggest, I am looking for the behaviour of this lib github.com/captain-miao/OptionRoundCardview but using the default CardView item. If it is not possible to change it individually, this lib is a good approach.
It requires the official MaterialCardView (which extends the androidx.cardview.widget.CardView) and at least the version 1.1.0 of the Material components library.
Add to your layout the MaterialCardView:
<com.google.android.material.card.MaterialCardView
style="#style/CustomCardViewStyle"
...>
</com.google.android.material.card.MaterialCardView>
Define a custom style inheriting a material card style (for example Widget.MaterialComponents.CardView) and use the shapeAppearanceOverlay attribute:
<style name="CustomCardViewStyle" parent="#style/Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">#style/ShapeAppearanceOverlay_card_custom_corners</item>
</style>
<style name="ShapeAppearanceOverlay_card_custom_corners" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopRight">4dp</item>
<item name="cornerSizeTopLeft">8dp</item>
<item name="cornerSizeBottomRight">16dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
You can also achieve it programmatically.
Just apply a custom ShapeAppearanceModel to the corners of the card.
Something like:
float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
cardView.getShapeAppearanceModel()
.toBuilder()
.setTopLeftCorner(CornerFamily.ROUNDED,..)
.setTopRightCorner(CornerFamily.ROUNDED,..)
.setBottomRightCorner(CornerFamily.ROUNDED,radius)
.setBottomLeftCornerSize(0)
.build());
Note: it requires the version 1.1.0 of the library.
With Jetpack compose you can use the shape parameter in the Card.
Something like:
Card(
shape = RoundedCornerShape(
topStart = 4.dp,
topEnd = 8.dp,
bottomEnd = 16.dp,
bottomStart = 2.dp,
)
){
Text("Content Card")
}
You can create a custom xml and name it rounded_corners.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"
android:topLeftRadius="20dp"
android:topRightRadius="30dp"
android:bottomLeftRadius="40dp"
android:bottomRightRadius="50dp"/>
<solid android:color="your_background_color" />
</shape>
And then use this as the background for your CardView:
android:background="#drawable/rounded_corners"
EDIT: I just noticed that this may work for all other views other than CardView, so refer to this question for seeing how to do a workaround.
NOTE: This here is a workaround if you want to achieve rounded corners at the bottom only and regular corners at the top. This will not work if you want to have different radius for all four corners of the cardview. You will have to use material cardview for it or use some third party library.
Here's what seemed to work for me:
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#F9F9F9">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#drawable/profile_bg"/>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="#+id/cvProfileHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="32dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="280dp"
android:orientation="vertical"
android:background="#drawable/profile_bg"
android:id="#+id/llProfileHeader"
android:gravity="center_horizontal">
<!--Enter your code here-->
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
There's two cardview's in all. The second cardview is the one that will have rounded corners (on all sides as usual) and will hold all other subviews under it. The first cardview above it is also at the same level (of elevation), and has the same background but is only about half the height of the second cardview and has no rounded corners (just the usual sharp corners). This way I was able to achieve partially rounded corners on the bottom and normal corners on the top. But for all four sides, you may have to use the material cardview.
In case, if you use ImageView inside CardView, you should change ImageView into ShapeableImageView. Normal ImageView only works with all corners not each corner.
Here is more detail example on material.io docs
themes.xml
<style name="MyCardView" parent="#style/Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">#style/MyCardViewOverlay</item>
</style>
<style name="MyCardViewOverlay">
<item name="cornerFamily">rounded</item>
<!-- below items does not work with normal ImageView -->
<item name="cornerSizeTopRight">0dp</item>
<item name="cornerSizeTopLeft">60dp</item>
<item name="cornerSizeBottomRight">0dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
layout.xml
<com.google.android.material.card.MaterialCardView
style="#style/MyCardView"
android:layout_width="200dp"
android:layout_height="200dp"
app:cardPreventCornerOverlap="false">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#color/orange_600"
app:shapeAppearanceOverlay="#style/MyCardViewOverlay" />
</com.google.android.material.card.MaterialCardView>
Hi you can add it programmatically or by xml with following code.
app:cardCornerRadius="0dp"// xml
cardView.setRadius(0);
this one is extra who is looking for elevation
app:cardElevation="0.7dp"//xml
app:cardMaxElevation="1dp"//xml
cardView.setCardElevation(2.1f);//code
cardView.setMaxCardElevation(3f);//code
The complete Java representation of the CardView’s XML.
CardView cardView = (CardView) findViewById(R.id.cardView);
cardView.setUseCompatPadding(true);
cardView.setContentPadding(30, 30, 30, 0);
cardView.setPreventCornerOverlap(true);
cardView.setCardBackgroundColor(Color.WHITE);
cardView.setCardElevation(2.1f);
cardView.setRadius(0);
cardView.setMaxCardElevation(3f);

ConstraintLayout constraints attribute in style

How to use constraint attributes in style?
When I'm trying to use it as any other attributes with custom namespace it's has no effect on my view.
<style name="Header.Center" parent="Header">
<item name="layout_constraintBottom_toBottomOf">parent</item>
</style>
Adding namespace app: is not helping.
First of all, make sure that the View that you're applying the style on is a direct child of the ConstraintLayout. Otherwise, the constraints will not be taken into account when positioning the View.
I have tried it and the way you tried does in fact work. I have added the following style to the styles.xml:
<style name="CustomStyle">
<item name="layout_constraintBottom_toBottomOf">parent</item>
<item name="layout_constraintEnd_toEndOf">parent</item>
</style>
Created a basic layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomStyle"/>
</android.support.constraint.ConstraintLayout>
And it does indeed position the TextView at the bottom right corner of the parent.
maybe your view's attribute is "match_parent",but it is wrong.
It should be "wrap_content".
<TextView
android:text="Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomStyle"/>

Button with style defined in XML works; not same if style set in code

I'm trying to add a style to a button in Xamarin Android from code, because the buttons will be generated dynamically and need to change colors based on other system events.
Using the code shown here, I expect that the two rows, one rendered from XML and the other from code, will look exactly alike. Instead, I see that the style ButtonDefaultTheme is only applied to the first row.
I know setting the style from code is possible based on this answer and this one. I think I could accomplish what I need using a layout inflater as in this answer, but I'm very curious why the code I have won't work.
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView (Resource.Layout.Main);
LinearLayout roomButtonLayout = FindViewById<LinearLayout>(Resource.Id.roomButtonLayout);
LinearLayout roomInfo = new LinearLayout(this)
{
Orientation = Orientation.Horizontal,
LayoutParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.MatchParent, 1f)
};
roomInfo.SetGravity(GravityFlags.CenterVertical);
roomInfo.SetPadding(20, 10, 0, 10);
TextView roomNameDisplay = new TextView(this)
{
Gravity = GravityFlags.Left,
TextSize = 20, // defaults to scaled pixels
Text = "Room 100",
LayoutParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WrapContent, LinearLayout.LayoutParams.WrapContent, 1f)
};
roomInfo.AddView(roomNameDisplay);
Button button2 = new Button(new ContextThemeWrapper(this, Resource.Style.ButtonDefaultTheme), null, 0)
{
Text = "View2"
};
roomInfo.AddView(button2);
roomButtonLayout.AddView(roomInfo);
}
}
In Main.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_height="wrap_content"
android:id="#+id/roomButtonLayout">
<LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingLeft="20dp"
android:paddingRight="0dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:gravity="left"
android:textSize="20sp"
android:text="Room 100"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:text="View1"
style="#style/ButtonDefaultTheme" />
</LinearLayout>
</LinearLayout>
In styles.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="ButtonDefaultTheme" parent="android:style/Widget.Holo.Button">
<item name="android:paddingBottom">0dp</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingLeft">10dp</item>
<item name="android:paddingRight">10dp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:minWidth">100dp</item>
</style>
</resources>
Result:
Minimum API level needed: 19
Compiling using: 21 in actual app, 23 in test app. Same visual results in both.

Is there a way to avoid size specifications on android layout?

I work with Android daily, and I would like to avoid the specifications of the views size.
For example, if I make a TextView, I got to assign Height and Width properties, like this:
<TextView
android:id="#+id/activity_lbl"
android:layout_width="wrap_content" <!-- Again -->
android:layout_height="wrap_content" <!--Again... --> />
<TextView
android:id="#+id/activity_lbl2"
android:layout_width="wrap_content" <!-- Again... -->
android:layout_height="wrap_content" <!--Again, for ever --> />
And for every view I create, I got to assign the same size specifications.
Is there a way to avoid them?
Declare it within a style that you'll apply in your layout files like this:
File: res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="wrapall">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>
And then apply it to your layouts like this:
<TextView
android:id="#+id/activity_lbl"
style="#style/wrapall" />
<TextView
android:id="#+id/activity_lbl2"
style="#style/wrapall" />
you can't avoid the
android:layout_width="wrap_content"
android:layout_height="wrap_content"
because it's important but i'm going to give you some codes for some layouts
for images you can use this in your class:
ImageView.getLayoutParams().height = YourHeightValue ;
ImageView.getLayoutParams().width = YourWidthValue;
for the textView use the Textview.setSize(); or TextView.setwidth(int); TextView.setHeight(int);

Android: Change text color in ListView for singleChoice

I have a listview set to use singleChoice. All I want to do is change the default background color to white and the text color to black. I cannot figure out how to do this. Here is my xml layout:
<ListView
android:id="#+id/lvSpeeds"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/llToolbar"
android:layout_below="#id/rgSpeedUnits"
android:textColor="#android:color/black"
android:choiceMode="singleChoice"
android:background="#ffffff"
android:cacheColorHint="#00ffffff"
android:clickable="true"
android:divider="#ff000000"
android:dividerHeight="1dp"
android:focusable="true"
android:scrollingCache="true" />
EDIT: I should have pointed out that I want to change this only using xml layout files and NOT in code. I already know how to do this in code. Using a custom layout other than android.R.layout.simple_list_item_single_choice forces you to implement an adapter, bind, write more code, and so on. From viewing a lot more posts, it does not appear possible to change the text color using only xml. In fact, it doesn't seem possible to change anything on a row as the underlying layout android.R.layout.simple_list_item_single_choice is not accessible.
for a list view Use android selector
like this
and save it with anyname.xml and giveits reference to background of your list
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#drawable/about_btn_hover"></item>
<item android:drawable="#drawable/about_btn"></item>
</selector>
and for changing text color add color folder in your res directory
create an xml save it textchangecolor.xml
and add the following lines to it
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#color/whiteColor"></item>
<item android:color="#color/bluetxt"></item>
</selector>
and give its refernce to the textcolor
try to this:
insert to this code in adapter in getview mathod:
LinearLayout mRowLayout = (LinearLayout) vi
.findViewById(R.id.list_item_layout);
final TextView title = (TextView) vi
.findViewById(R.id.list_item);
title.setText(Massage[position]);
mRowLayout.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
title.setTextColor(Color.RED);
});
here list_item code:
<?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/list_item_layout"
android:orientation="vertical" >
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/row_single"
android:layout_margin="5dp">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#android:color/black"
android:padding="10dp"
android:textSize="16sp"
android:layout_toLeftOf="#+id/arrow"
android:id="#+id/list_item"/>
</RelativeLayout>
</LinearLayout>
The best solution I could find was to use styles.xml and set a theme for my dialogs.
styles.xml
<style name="DialogTheme" parent="AppTheme">
<item name="android:textColor">#color/text</item>
<item name="android:textColorAlertDialogListItem">#color/text</item>
+ other styles
</style>
In Java Built Dialogs:
ContextThemeWrapper theme;
theme = ContextThemeWrapper(view.getContext(), R.style.DialogTheme);
AlertDialog.Builder builder = new AlertDialog.Builder(theme);
In XML built Dialogs:
<myLayout
....
android:theme="#style/DialogTheme" />

Categories

Resources