(Sorry for my poor question. I have update it now)
How can i make it in XML file? I tried to use following code, but not correct (I used "android:rotation="-90" to do rotation.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="141dp"
android:layout_height="200dp"
android:layout_weight="0.41"
android:orientation="vertical" >
<EditText
android:id="#+id/sidebar_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/shape_card_sidebar"
android:inputType="text"
android:rotation="-90"
android:text="I want to be like this" >
</EditText>
</FrameLayout>
You're going to run into several problems if you try to do it that way. The most obvious issue will be the incorrect measurement. Instead you should create a custom view. Something like this:
public class RotatedTextVew extends TextView {
public RotatedTextView(Context context) {
super(context);
}
public RotatedTextView(Context context, AttributeSet attrs) {
super(context, attrs)
}
public RotatedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Switch dimensions
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.rotate(90);
super.onDraw(canvas);
canvas.restore();
}
}
I haven't actually tested this, but this is how I'd start.
Replace your FrameLayout with <Relative> or <LinearLayout>. Also set android:gravity="center" property of parent layout.
Related
I have opened a bug report at https://bugs.chromium.org/p/chromium/issues/detail?id=1144713
When I rotate the webview it does not fill the screen.
I want to rotate the webview because AndroidTV requires landscape mode... but we are gonna have the TV in a portrait setting.
i use fill_parent && match_parent but it does not work in either case.
here is a screen shot of Android Studio preview.
Also to note when i test it like this it seems like the webview matchs the screen size but doesn't adapt to the rotation... it just rotates the webview and does not resize it to the new dimensions
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="#drawable/game_bg"
android:orientation="vertical"
tools:context="com.surveyswithgames.app.wheel.KeypadActivity">
<FrameLayout
android:id="#+id/frameParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_marginLeft="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:background="#android:color/transparent"
android:foregroundGravity="center"
android:keepScreenOn="true">
<WebView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/keypadWebView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rotation="-90"
/>
</FrameLayout>
</RelativeLayout>
UPDATE:
Based on the answer https://stackoverflow.com/a/64672893/1815624 I used a custom WebView class, yet it seems like setMeasuredDimension is not functioning...
public class CustomWebView extends WebView {
public CustomWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomWebView(Context context) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int desiredWidth = MeasureSpec.getSize(heightMeasureSpec);//getMeasuredHeight();
int desiredHeight = MeasureSpec.getSize(widthMeasureSpec);//getMeasuredWidth();
Log.e("CustomWebView", "desiredWidth: "+ desiredWidth);
Log.e("CustomWebView", "desiredHeight: "+ desiredHeight);
setMeasuredDimension(desiredWidth, desiredHeight);
}
}
UPDATE 2:
I had to use the code and layout suggested by the answer https://stackoverflow.com/a/64672893/1815624 and then it worked...Cheers
The issue that you are having is that rotation occurs post-layout. This means that the measurements occur for the landscape mode (width > height) then the view is rotated but the new width is the old height and the new height is the old width. That is what you are seeing and it is not a bug.
One way around this is to create a custom view that swaps the width and height and pivots at the origin -90 degrees then translates the whole view down by the desired height.
Here is the code for the custom view:
RotatedWebView.kt
class RotatedWebView #JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredWidth = MeasureSpec.getSize(heightMeasureSpec)
val desiredHeight = MeasureSpec.getSize(widthMeasureSpec)
translationY = desiredWidth.toFloat()
setMeasuredDimension(desiredWidth, desiredHeight)
}
}
RotatedWebView.java
public class RotatedWebView extends WebView {
public RotatedWebView(Context context) {
super(context);
}
public RotatedWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RotatedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = MeasureSpec.getSize(heightMeasureSpec);
int desiredHeight = MeasureSpec.getSize(widthMeasureSpec);
setTranslationY(desiredWidth);
setMeasuredDimension(desiredWidth, desiredHeight);
}
}
The layout will look something like this:
activity_main.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/frameParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginStart="2dp"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:background="#android:color/transparent"
android:foregroundGravity="center"
android:keepScreenOn="true">
<com.example.webviewrotation.RotatedWebView
android:id="#+id/keypadWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rotation="-90"
android:transformPivotX="0dp"
android:transformPivotY="0dp" />
</FrameLayout>
</RelativeLayout>
And this is the result as seen in an emulator:
It would probably be better to place all the view manipulation into the custom view instead of splitting it between the code and the XML. I assume that you will physically rotate the TV so the web page shows as you want.
I am using a TextView which has to rotate at angle at 35 degrees. I have successfully created a rotated textview but I can't fill the complete screen. Basically I want to complete 2 objectives-
1)Make the textview occupy the whole screen
currently it is showing it like this-
I wanna fill the space left in the top left corner. I covered the other three corners by the help of #Alexandre's answer. #Thanks Alexandre.
CustomTextView.java
public class CustomTextView extends android.support.v7.widget.AppCompatTextView {
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec*2, heightMeasureSpec*3);
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:orientation="vertical">
<com.dakshansh.partytimevendorsapp.CustomTextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="-35"
<!--Hope I don't need to change text.Text is too much more.-->
android:text="Galleries" />
</LinearLayout>
2)Make the text justified
As you can see my text is left aligned & as I am trying to create a pattern, I would require the text to be justified
One solution would be to create a CustomTextView that extends TextView overriding [onMeasure](https://developer.android.com/reference/android/view/View.html#onMeasure(int, int)).
For example :
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec*2, heightMeasureSpec*2);
}
This would make your textView 4 times bigger filling the white spaces.
PS: I haven't tried this code.
I'm facing this weird problem where I have a custom view (with custom drawing) overriding ToggleButton, and for some reason overriding the onDraw and draw methods do not prevent the parent class from drawing a part of it, which makes my view look like it's glitched.
This bug seems to be happening only with API level 25, on a physical device or on the emulator.
Using the following code for my custom toggle Button:
public class CustomToggleButton extends ToggleButton {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomToggleButton(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
//nope, not drawing anything
}
#Override
public void draw(Canvas canvas) {
//nope, not drawing anything
}
}
And the following simple XML layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:text="Bottom left: buggy custom ToggleButton.\nBottom right: regular ToggleButton." />
<test.com.togglebuttonbug.CustomToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|left"
android:textOff="B"
android:textOn="A" />
<ToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|right"
android:textOff="B"
android:textOn="A" />
</FrameLayout>
The result is the following:
If you look carefully at the screenshot, you can see that for the phone on the right, at the bottom left, instead of having nothing like the empty draw methods should do, you can see a piece of gray drawing.
Would anybody have an idea of what could be causing this? Is that a bug on Android N?
I'm showing a video in a videoview:
In my XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="fill_parent">
<VideoView
android:layout_gravity="center"
android:id="#+id/videoview_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
It looked like this works perfect. The video resizes itself so the screen is filled, while the video remains it's aspect ratio.
But on tablets, after like 30 - 60 seconds in portrait orientation, the video stretches to full screen. (It doesn't maintain the aspect ratio, it stretches the height)
Like this:
I ended up subclassing the VideoView:
public class PlayerVideoView extends VideoView{
private int mForceHeight = 0;
private int mForceWidth = 0;
public PlayerVideoView(Context context) {
super(context);
}
public PlayerVideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PlayerVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setDimensions(int w, int h) {
this.mForceHeight = h;
this.mForceWidth = w;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mForceWidth, mForceHeight);
}
}
Where in the onCreate i set the dimensions
videoView.setDimensions(800, 600);
Then in the
#Override
public void onConfigurationChanged(Configuration newConfig) {..}
I manually set the dimensions for portrait or landscape, depending on the users device orientation.
The issue is solved just by removing the video view alignment from the parent and making it centre in the Relative layout.
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<VideoView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="#+id/videoView" />
</RelativeLayout>
Looking to make a small Android Compound View/Custom Component, where a FrameLayout is extended so that it has its own fully overlaying "Cover" view (that can intercept clicks and ripple) without repeating that cover in every XML instance.
I don't know whether it is best practice to re-layout the covering View in the Custom FrameLayout's onMeasure or onLayout methods, or if there's a simple XML trick that I'm missing (outside of just using a RelativeView since that would draw and re-draw the layout very often, but if I'm wrong here too correct me please)
CoveredFrameLayout.class
public class CoveredFrameLayout extends FrameLayout {
private View coverView;
public CoveredFrameLayout(#NonNull Context context) {
this(context, null);
}
public CoveredFrameLayout(#NonNull Context context, #Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CoveredFrameLayout(#NonNull Context context, #Nullable AttributeSet attrs, #AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
inflate(context, R.layout.widget_covered_framelayout, this);
//
setBackgroundColor(ContextCompat.getColor(context, R.color.light_red));
coverView = findViewById(R.id.widget_cover);
//
coverView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
coverView.animate()
.alpha(0)
.setDuration(1000)
.withEndAction(new Runnable() {
#Override
public void run() {
coverView.setVisibility(GONE);
}
})
.start();
view.setOnClickListener(null);
}
});
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
}
widget_covered_framelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<View
android:id="#+id/widget_cover"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#color/transparent_yellow400"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
android:visibility="visible" />
</merge>
The XML CoveredFrameLayout being used
<com.example.oliver.content.ui.widgets.CoveredFrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="hello" />
</com.example.oliver.content.ui.widgets.CoveredFrameLayout>
And here's a screenshot of what this is looking like currently. Just trying to learn the best practice to get that yellow square to dynamically cover the whole FrameLayout! Thanks y'all!
Here is the end goal result, however this result was only achieved by hardcoding the Cover View's height and width to the pre-calculated height and width in pixels of the view itself. A dynamic version of this could work fine, but I don't know what is the best practice for where in the onMeasure/onLayout cycle to put this code.