Android: Switch Height and Width when View change orientation - android

I do use PhotoView library to ZoomIn-Out.
now when user click a button i prepared to rotate the PhotoView, Height and Width would rotate.
so width which is smaller than the screen Height.
and this result in i can't get the full screen zoom like usual before Rotating the Imageview.
so any solution to make the new width or height after rotation to take full screen.
Example : this is Zoomed Image it doesn't zoom in the entire screen like before the rotation

I had to work with the same type of feature on my project and here was my design and implementation for it.
Basic XML design for photo view
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.github.chrisbanes.photoview.PhotoView
android:id="#+id/image_main"
android:layout_width="0dp"
android:scaleType="centerCrop"
android:layout_height="400dp"
android:src="#drawable/gull_portrait_ca_usa"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/image_rotate"
android:src="#android:drawable/ic_menu_rotate"
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="40dp"
android:layout_height="40dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Then I just update the orientation onClick event.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.imageRotate.setOnClickListener {
binding.imageMain.rotation = binding.imageMain.rotation+90
}
}
}
Output

You'll need to create 2 xml layout. The portrait (the one you have already created inside res > layout folder) and the landscape (inside res > layout-land).
When you rotate the phone, fragment will load the xml file inside layout-land folder.
You can find a tutorial here: https://www.geeksforgeeks.org/how-to-create-landscape-layout-in-android-studio/
And more info here: https://developer.android.com/guide/topics/resources/providing-resources

If Image will be rotated, it will adjust in the screen as per his aspect ratio. If you want to fit it to full screen, the image will starched that will not look good. If still you want to do it, simply use the Image as 'background' at the place of 'Image Resources' and keep the view length and width as 'match parent'.
See below sample view:
<ImageView
android:id="#+id/mainImageID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/yourImage"/>

Related

Popup menu uses original size of Image as anchor, instead of actual size

I am having an image view displaying a nice image and opening a popup-menu on tap.
The images I use have different sizes in original, so the imageView has a static width.
However when I anchor the pop-up-menu at the imageView, it uses the original sized image as anchor, which results in very weird views. (Screenshots appended)
Of course I could size all images on the same size, but since the images are having sizes in px and not dp, it would lead to problems on screens with a different screen-resolution.
Is this an error in my code or a bug of the pop-up menu? Wanted to file it as bug, but it´s pretty much impossible to find the place to do so either.
Here´s my xml for the imageView (image view having a default icon):
<ImageView
android:id="#+id/languageFlag"
android:layout_width="24dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/activity_vertical_margin"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="#id/searchView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/searchView"
app:layout_constraintTop_toTopOf="#+id/searchView"
app:srcCompat="#drawable/ic_baseline_casino_24" />
Here´s my xml for the whole fragment (Just in case this matters):
<FrameLayout 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="match_parent"
android:layout_height="match_parent"
tools:context="bi.deutsch_kirundi_app.fragments.DictionaryFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/lightgrey">
<ImageView
android:id="#+id/languageFlag"
android:layout_width="24dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/activity_vertical_margin"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="#id/searchView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/searchView"
app:layout_constraintTop_toTopOf="#+id/searchView"
app:srcCompat="#drawable/ic_baseline_casino_24" />
<SearchView
android:id="#+id/searchView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:layout_marginLeft="#dimen/activity_vertical_margin"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:background="#color/white"
android:iconifiedByDefault="false"
app:layout_constraintEnd_toStartOf="#id/languageFlag"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
</SearchView>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/result_fragment"
android:name="bi.deutsch_kirundi_app.fragments.dictionary.AllVocabularyFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="#dimen/activity_vertical_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/searchView"
tools:layout="#layout/fragment_all_vocabulary" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
In the "onCreateView"-method of my fragment, I get the imageView, get the images ids and set the one for the corresponding language saved in SharedPreferences. (Logically)
languagePicker = view.findViewById(R.id.languageFlag)
val sharedPreferences = view.context.getSharedPreferences(App.APP_PREFERENCES, Context.MODE_PRIVATE)
val lastChosenTranslationDirection = sharedPreferences.getInt(App.TRANSLAT_KEY, 0)
val ids = view.context.resources.getStringArray(R.array.translation_direction_flags)
images = Array(ids.size) {
val imageId = resources.getIdentifier(ids[it], "drawable", activity?.packageName)
ContextCompat.getDrawable(view.context, imageId)
}
languagePicker.setImageDrawable(images[lastChosenTranslationDirection])
Then I am setting the onclick-listener on the imageView (languagePicker) the following:
languagePicker.setOnClickListener {
val dropDownMenu = PopupMenu(it.context, languagePicker)
val languages = it.resources.getStringArray(R.array.translation_directions)
for(index in languages.indices) {
dropDownMenu.menu.add(0, index, index,
languages[index])
dropDownMenu.show()
dropDownMenu.setOnMenuItemClickListener(this)
}
}
Seems fine to me, but maybe I am blinded. Is there a need to add some specific property to the imageview, so the size of the Drawable is also adapted?
EDIT: I don´t want the width of the PopUp-Menu to be changed. Rather I want the Popup-Menu to use the ImageView as anchor, not the originally sized image. As visible on the screenshot with the German Flag, it is pushed to the bottom instead of sticking to the ImageView.
The width of the PopupMenu item layout actually doesn't have anything to do with the size of the original images set on the ImageView. The item layouts for PopupMenus simply have a minimum default width, and I don't think you can change it.
I would suggest that you switch to using Spinner, PopupWindow, or ListPopupWindow. These allow you to set your own item layouts, so you can choose exactly how you want each item to look.
I believe the default item layout for a Spinner just has its width set to the widest item in the list, so that might be the easiest route:
https://developer.android.com/guide/topics/ui/controls/spinner

AndroidTV Leanback library default navigation scaling makes vector drawable edges scratched, jagged, ugly

Inserting VectorDrawable graphic inside viewholders in main grid of leanback makes them look ugly when focused. There is some scaling issue that i cannot resolve.
Here is simple example in normal application:
ic_vawe.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="986.5dp"
android:height="87.27dp"
android:viewportWidth="986.5"
android:viewportHeight="87.27">
<path
android:fillColor="#FF000000"
android:pathData="M464.46,86.61c-24.27,0.49 -63.93,0.66 -62,0.66h584V26.68C716.37,26.72 694.13,78.17 464.46,86.61Z"
android:strokeAlpha="0.5"
android:fillAlpha="0.5"/>
</vector>
Activity.kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var iv = this.findViewById<ImageView>(R.id.imageView_1);
var d3 = ContextCompat.getDrawable(this, R.drawable.ic_wave);
iv.setImageDrawable(d3);
iv.setOnClickListener {
iv.scaleY = iv.scaleY + 0.6F;
}
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
When im scaling this vector up, then i got those shattered edges (look at video):
That behaviour is extremely visible when navigating in AndroidTV Leanback library where there is a lot of navigation related scaling. Image is sharp only in one state... Look at those ugly edges:
Please, help me smooth this edges od VectorDrawables in android TV project. Do you have any ideas?
Please try use PNGs images instead of xml drawables.

Weird behavior when using ConstraintLayout as the root layout of a DialogFragment

I am constructing a custom dialog using a DialogFragment. I've noticed very odd behavior with various ViewGroups used as the root of the dialog's layout. I assume this is due to some strange interaction between the system's windows and how it displays dialogs. In this particular instance, I am using a ConstraintLayout as the root view of the layout.
When displayed, the dialog extends to the edges of the screen, and the Layout Inspector shows a measured width of over 16,000,000. Even weirder is that the ConstraintLayout defines padding, which can still be seen on the screen.
Below is the dialog's class:
public class AgreementDialog extends DialogFragment {
// Bindings..
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_agreement, container);
ButterKnife.bind(this, view);
return view;
}
}
Here is the layout, dialog_agreement:
<android.support.constraint.ConstraintLayout
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="wrap_content"
android:layout_height="wrap_content"
android:background="#fff"
android:padding="#dimen/margin_large"
android:layout_margin="#dimen/margin_xlarge"
>
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_standard"
android:text="this is some text. "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/checkbox"
/>
<TextView
android:id="#+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_large"
android:text="123456789"
app:layout_constraintBottom_toTopOf="#+id/negative"
app:layout_constraintTop_toBottomOf="#id/description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<Button
android:id="#+id/positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/confirm"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="24dp"/>
<Button
android:id="#+id/negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="#string/cancel"
app:layout_constraintBaseline_toBaselineOf="#id/positive"
app:layout_constraintEnd_toStartOf="#id/positive"
/>
</android.support.constraint.ConstraintLayout>
Questions:
Why is the measured width such a large number?
Given the measured width at over 16,000,000, one would expect the end padding to also be off screen. Why is it visible?
How can these issues be remedied so that a normal dialog that wraps it's content can be displayed?
EDIT: I've noticed that removing the padding seems to cause the width to hit that large number. Keeping the padding causes the dialog to maintain a normal margin to the edge of the screen, but clips the content.
I created a sample app with your layout dialog_agreement.xml, and it worked properly:
1. Why is the measured width such a large number?
The layout dialog_agreement.xml refers to dimension resources:
#dimen/margin_standard
#dimen/margin_large
#dimen/margin_xlarge
If their values are not moderate, the dialog will be weired.
2. Given the measured width at over 16,000,000, one would expect the end padding to also be off screen. Why is it visible?
According to the guide, each child view makes a wish for its size. But the parent view initially takes into account its own padding. So, the dialog will be within the screen size, and also retain its padding.
The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.
The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent. ...
The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. ...
To measure its dimensions, a view takes into account its padding. ...
3. How can these issues be remedied so that a normal dialog that wraps it's content can be displayed?
Set moderate values in res/values/dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="margin_standard">16dp</dimen>
<dimen name="margin_large">16dp</dimen>
<dimen name="margin_xlarge">16dp</dimen>
</resources>
The sample app showed AgreementDialog as in the screenshot above.
Try using MaterialDialog as a custom dialog with your fragment inside . It is not the right answer for your question but It would simplify your work a lot .
https://github.com/afollestad/material-dialogs

Android: Programmatically changing XML layout to "Lefty Flip"

I'm trying to allow users of my app to toggle the UI to be either standard orientation or "lefty flip". I'm unsure how low-level of a solution I need to program, considering Android might provide an abstracted way to easily do this.
Visually, the standard orientation would be:
and the lefty flip orientation would be:
So, currently what I'm thinking of attempting is a manual rearrangment of the xml layout, component by component, within a menu button's onTouch() logic.
I get the feeling that there may be a simpler way than this. Any suggestions? Is a series of programmatic calls to rearrange the view the best way? Xml file below.
<?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:orientation="horizontal"
android:baselineAligned="false"
android:keepScreenOn="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.40"
android:orientation="vertical"
android:id="#+id/toolbarGestureOverlay" >
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="3.60"
android:id="#+id/openglsurface">
</LinearLayout>
</LinearLayout>
I think you can achieve it by using rotate function (from API 11 only):
View view = findViewById(R.id.yourParentLayout);
view.setRotation(270);
// you must canculate your screen size to make your view fit your screen.
view.getLayoutParams().width = 800;
view.getLayoutParams().height = 480;
// For flip, you can rotate a long x or y axis:
view.setRotationY(180);

How to overlay an image above all activities in android

I want to overlay an image above all activities after some operation to have a feel like phone is locked. How can I do this programmatically in android ?
You can set a FrameLayout at the end of you XML layout file with an ImageView and "match_parent" dimension for both length and height. Set it's visibility to "gone" in the XML layout file. and the problematically in your code change it's visibility to visible to show this full screen Image and hide all the other components that are laid below it.
For example in your XML file put this at the end of the XML:
<FrameLayout
android:id="#+id/lockScreenLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" >
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/your_iamge"
android:contentDescription="#drawable/your_iamge" />
</FrameLayout>
So it would be the child of your root xml element.
and then in code, do this:
lockScreenLayout = (FrameLayout) findViewById(R.id.lockScreenLayout);
lockScreenLayout.setVisibility(View.VISIBLE);
One simple solution consists in setting your image as the background of the root view of your activities.

Categories

Resources