Inside hollow shape rectangle drawable / canvas shape - android-layout

I'm trying to create a drawable shape with stroke for my popup layout background.
and
I tried to play around with radius but didn't get the desired result.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="?colorSecondary" android:width="1dp"/>
<solid android:color="?colorSurface"/>
<corners
android:topLeftRadius="#dimen/card_corner_radius"
android:topRightRadius="#dimen/card_corner_radius"
android:bottomLeftRadius="#dimen/card_corner_radius"
android:bottomRightRadius="#dimen/card_corner_radius" />
</shape>
I tried with the canvas but cannot achieve second picture

Why can't you simply use the graphics that you posted as a PNG file? Other options follow.
You could decompose your drawing to its components and build a LayerList drawable from the components. For instance, your first image looks like is is composed of two horizontal lines and arcs of ovals at either end. Four drawables, each representing one of these figures and stacked would produce your first image. It would be similar for the second image.
Since you already have the image you want, you could paste it into a vector graphic editing program such as InkScape, export the SVG file and import the SVG file into Android Studio (File->New->Vector Asset and select local SVG file). I did this with your second image and came up with the following:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="145.83989dp"
android:height="26.347599dp"
android:viewportWidth="516.7555"
android:viewportHeight="93.357635">
<path
android:pathData="m10,93.107c-8.631,-0.552 -9.5,-0.79 -9.5,-2.607 0,-1.877 0.86,-2.036 14.026,-2.58 15.353,-0.635 17.206,-1.257 21.838,-7.331 6.399,-8.389 7.237,-21.039 2.028,-30.609 -3.638,-6.685 -6.619,-8.98 -11.661,-8.98 -2.2,0 -5.739,-0.521 -7.865,-1.158 -3.309,-0.991 -3.866,-1.567 -3.866,-4 0,-1.859 -0.519,-2.842 -1.5,-2.842 -0.825,0 -1.5,-0.675 -1.5,-1.5 0,-1.876 1.394,-1.935 2.899,-0.122 0.629,0.758 3.497,1.62 6.372,1.917 2.876,0.296 6.235,0.852 7.466,1.235 1.739,0.541 3.006,-0.072 5.691,-2.758 1.9,-1.9 3.755,-4.654 4.123,-6.12 1.726,-6.878 -2.782,-14.742 -9.625,-16.793 -2.649,-0.794 -3.926,-1.753 -3.926,-2.949 0,-1.043 -0.926,-1.951 -2.25,-2.206 -2.005,-0.386 -1.963,-0.448 0.393,-0.57 1.454,-0.075 2.902,-0.811 3.219,-1.636 0.509,-1.327 26.338,-1.5 224.138,-1.5 193.862,0 223.636,0.192 224.116,1.443 0.42,1.093 1.703,1.307 5.302,0.88 10.074,-1.193 22.04,5.074 28.511,14.931 12.842,19.565 10.573,48.147 -5.032,63.388 -2.896,2.828 -7.279,5.911 -9.741,6.851 -2.766,1.056 -4.677,2.481 -5.004,3.73l-0.528,2.02 -229.812,-0.372c-126.396,-0.204 -231.837,-0.098 -234.312,0.235 -2.475,0.334 -8.775,0.334 -14,0zM470,87c-1.098,-0.71 -0.362,-0.973 2.75,-0.985 2.338,-0.008 4.253,-0.353 4.255,-0.765 0,-0.412 2.816,-0.778 6.25,-0.813 7.354,-0.075 11.176,-1.816 17.191,-7.83 13.89,-13.89 15.272,-41.457 2.892,-57.69 -7.683,-10.075 -19.195,-14.271 -28.588,-10.42 -1.202,0.493 -1.75,0.254 -1.75,-0.765 0,-0.86 -1.312,-1.744 -3.125,-2.107 -1.719,-0.344 -100.528,-0.625 -219.577,-0.625L33.847,5l3.219,2.709c8.558,7.201 9.075,19.05 1.198,27.474l-2.508,2.682 3.532,4.318c4.135,5.055 7.713,14.889 7.713,21.197 0,5.993 -3.103,15.578 -6.473,19.997l-2.757,3.615 109.365,0.259c300.91,0.712 324.326,0.694 322.865,-0.25zM453.667,70.333c-0.367,-0.367 -0.667,-1.132 -0.667,-1.7 0,-0.627 0.466,-0.568 1.183,0.15 0.651,0.651 0.951,1.416 0.667,1.7 -0.284,0.284 -0.817,0.217 -1.183,-0.15zM0,80.5c0,-0.825 0.177,-1.5 0.393,-1.5 0.216,0 0.652,0.675 0.969,1.5 0.317,0.825 0.14,1.5 -0.393,1.5 -0.533,0 -0.969,-0.675 -0.969,-1.5z"
android:fillColor="#000000"/>
</vector>
Which looks like this when displayed in an ImageView:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:adjustViewBounds="true"
android:src="#drawable/ic_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The image can be scaled and accurately reflect the original image at any size screen. You can use any graphics editor that can produce an SVG file.

Related

Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?

Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?
<TextView
android:id="#+id/textView21_id"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_x="22dp"
android:layout_y="105dp"
android:height="50dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:textSize="30sp"
android:textColor="#000000"
android:background="#9999cc"
android:singleLine="false"/>
There's the activity_main.xml snippet. Is there something there which overrides the SetLeftTopRightBottom?
I am still trying to get two different but ordinary mobile phones (cell phones) to display a view the same.
pic of same app in two phones
You can see the left hand pic shows to below the grey '6:' textview and includes the 'Go' textview and all the right hand 5th-letter-in-the-word textview areas whereas the other pic doesn't.
I've figured out how to get each phone's display metrics
var metrics = Resources.DisplayMetrics;
gnumWidthDp = ConvertPixelsToDp(metrics.WidthPixels);
gnumHeightDp = ConvertPixelsToDp(metrics.HeightPixels);
I thought it would be easy to do the SetLeftTopRightBottom thing and set each textview in the right place.
Please can you tell me what I have missed? Thank you all.
In the official document, SetLeftTopRightBottom method is meant to be used in animations only as it applies this position and size for the view only temporary and it can be changed back at any time by the layout.
More information: https://developer.android.com/reference/android/view/View#setLeftTopRightBottom(int,%20int,%20int,%20int)
In addition, the size of the textview21 had been ensured in the xml. If you want to set the size of it dynamically, you need to use the LayoutParams. Such as:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 200);
//300 is width and 200 is height
textView.LayoutParameters = layoutParams;

Handling GONE views puzzle in ConstraintLayout

I have a simple enough looking layout with what turns out to be quite a tricky behaviour to accomplish using xml alone i.e. using only the features of ConstraintLayout and not having to do anything programmatically.
I have considered Barriers & Guidlines and many scenarios and trials with no success; so this is my last hope that maybe someone else knows something I don't.
Here is my puzzle:
If 3 lines visible -> image should be centred between line 1 and line
2
If 2 lines visible -> image should be centred between line 1 and
line 2
If 1 line visible (label_text) -> image should be centred in parent, or
centre aligned with line 1 (label_text)
Here are some images to illustrate:
3 Lines - correct
2 Lines - correct
1 Line incorrect but best I can get so far [when only Label is visible]
1 Line correct the way I want it to be [when only Label is visible]
Code:
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/V2.ItemList.Background"
android:minHeight="#dimen/item_minimum_height"
android:paddingVertical="#dimen/=margin_vertical">
<ImageView
android:id="#+id/icon"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:src="#drawable/ic_img"
tools:visibility="visible" />
<TextView
android:id="#+id/label_text"
app:layout_constraintBottom_toTopOf="#id/line1_text"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Label" />
<TextView
android:id="#+id/line1_text"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toTopOf="#id/line2_text"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon"
app:layout_constraintTop_toBottomOf="#id/label_text"
tools:text="Line 1"
tools:visibility="gone" />
<TextView
android:id="#+id/line2_text"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon"
app:layout_constraintTop_toBottomOf="#id/line1_text"
tools:text="Line 2"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any help is much appreciated!
UPDATE
See Cheticamp's answer below which is best solution but in case it's useful for anyone else here's the way I was going to do it programmatically if I couldn't find an xml only solution:
private fun adjustConstraints() {
if(binding.line1Text.isGone && binding.line1Text.isGone) {
ConstraintSet().apply {
clone(binding.itemListLayout)
// Adjust left/start content for single line
connect(
R.id.icon,
ConstraintSet.TOP,
R.id.item_list_layout,
ConstraintSet.TOP
)
connect(
R.id.icon,
ConstraintSet.BOTTOM,
R.id.item_list_layout,
ConstraintSet.BOTTOM
)
// Adjust right/end content for single line
connect(
R.id.right_content,
ConstraintSet.TOP,
R.id.item_list_layout,
ConstraintSet.TOP
)
connect(
R.id.right_content,
ConstraintSet.BOTTOM,
R.id.item_list_layout,
ConstraintSet.BOTTOM
)
}.also {
it.applyTo(binding.itemListLayout)
}
}
}
Constrain the ImageView to the top of label_text and to the bottom of line_1_text.
<ImageView
android:id="#+id/icon"
app:layout_constraintTop_toTopOf="#id/label_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#id/line1_text"
tools:src="#drawable/ic_img"
tools:visibility="visible" />

getSupportActionBar().setCustomView(view, layout); does not cover entire actionbar

I'm trying to set a custom actionbar background but it does not fill up the entire space.
it leaves like a 5dp grey actionbar from left side.
I used the following:
android.support.v7.app.ActionBar.LayoutParams layout = new android.support.v7.app.ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT, android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(view, layout);
getSupportActionBar().setDisplayShowCustomEnabled(true);
this is my custom actionbar xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="fill_horizontal"
android:background="#color/actionbar_color"
></RelativeLayout>
I have tried different styles but none worked.
please help
fixed it by doing:
//to set same background color on entire actiobar
getSupportActionBar().setBackgroundDrawable( getResources().getDrawable(R.drawable.actionbar_color));
//to display custom layout with same BG color
android.support.v7.app.ActionBar.LayoutParams layout = new android.support.v7.app.ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT, android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(view, layout);
getSupportActionBar().setDisplayShowCustomEnabled(true);

Android TextView Programmatically following XML

I currently have this xml:
<TextView android:id="#+id/dummy"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/test"
android:textStyle="bold" />
And im trying to convert it to a java version so that I can set a typeface:
setContentView(R.layout.activity_main);
// the get the activity_main layout (getContentView method does not exist?)
FrameLayout layout = (FrameLayout) findViewById(android.R.id.content);
final TextView textView = new TextView(context);
textView.setId(R.id.dummy);
FrameLayout.LayoutParams contentLayout = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
contentLayout.gravity = Gravity.CENTER;
textView.setText(R.string.test);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
textView.setTypeface(tf);
layout.addView(textView, contentLayout);
The problem I'm having is that either does not gravity work or match_parent. The texts ends up in the upper right corner and not in the center as it does on the xml version.
In the XML you're setting the gravity of the text inside the TextView. In the code you are setting the TextView's layout gravity.
To replicate what you've done in the XML, change the line:
contentLayout.gravity = Gravity.CENTER;
to:
textView.setGravity(Gravity.CENTER);
If your XML had android:layout_gravity="center" instead of android:gravity="center" then your code would match as it is.

TextView gravity="top" but changing font size dynamically doesn't keep text align to the top

I have an app that needs to dynamically align text views over certain locations on an image. The image is scaled to fit the view. Text entries are added by the user. I'm using a RelativeLayout and margins to properly position the text. All is good.
When the user rotates the screen, I save the text locations and bitmap using onRetainNonConfigurationInstance(). When the view is recreated, I add the views back into the RelativeLayout. Now, because the view is a different size, the scale of the image is different. To keep the text boxes in the same location, I have to account for that. I have all that code working except for one issue....
If I create a TextView and set the fontSize to a small size (e.g. <11px), the top of the text box is positioned where I want it to be but the text is aligned with a baseline as if it were 11px font. I don't know the scale factor in the onCreate method so I can't change the font size until after onMeasure and onLayout are called. I've tried forceLayout() and requestLayout() but nothing seems to fix the alignment problem.
Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
>
<com.xyx.ScalableLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
android:clickable="true"
android:gravity="top"
>
<com.xyx.ScaledImageView
android:id="#+id/formView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
/>
<com.xyx.ScalableLayout>
</ScrollView>
A textView is added with the following code:
textView = new TextView(getContext());
textView.setPadding(0, 0, 0, 0);
textView.setSingleLine();
textView.setFocusableInTouchMode(false);
textView.setClickable(false);
textView.setGravity(Gravity.TOP);
textView.setText(entry.mText);
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
params = new RelativeLayout.LayoutParams(
ViewGroup.MarginLayoutParams.WRAP_CONTENT,
ViewGroup.MarginLayoutParams.WRAP_CONTENT);
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
addView(textView, params);
When ScaledImageView gets an onSizeChanged() callback, it sets the scale value and updates the font size and location of TextViews with the following code:
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
PointF viewLoc = computeTopLeft(entry, entry.mTextView.getPaint());
params = (RelativeLayout.LayoutParams) textView.getLayoutParams();
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
textView.setLayoutParams(params);
textView.forceLayout();
And finally, I do a
requestLayout() on the ScalableLayout
I know that's a lot of code but my problem is this. If I know the proper scale factor (used in mapSizeToView()) when I am creating the TextView and adding it to the screen everything works fine. If the value is incorrect, then nothing I can find will do a full recalculate that will get the TextView to be the same as if it were created with that font size. I believe it is tied to Android Layout structure which I generally understand. However, I don't understand why I can't get it to recompute from scratch (short of tearing down all the views and recreating them).

Resources