I want to change the ExpandableListView group indicator to right with padding.
I used custom adapter to load data to ExpandableListView.
This is my ExpandableListView xml.
<ExpandableListView
android:id="#+id/Ex_offers"
android:layout_width="250dp"
android:layout_height="400dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:childDivider="#00000000"
android:groupIndicator="#drawable/settings_selector"
android:listSelector="#android:color/transparent">
</ExpandableListView>
This is GroupView xml
<TextView
android:id="#+id/lblListHeadertwo"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#drawable/transperant_bar"
android:fontFamily="Lato"
android:paddingLeft="15dp"
android:textColor="#daac56"
android:textStyle="bold"
android:textSize="17sp"
android:paddingTop="8dp" />
This is ChildView xml
<TextView
android:id="#+id/text_offers"
android:layout_width="300dp"
android:layout_height="20dp"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#drawable/transperant_bar"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:textColor="#daac56"
android:textSize="14sp"/>
<ImageView
android:id="#+id/img"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginLeft="12dp"/>
This is the output image, I want to set margin to this indicator.
setIndicatorBounds(int, int) does not work properly for Android 4.3.
They introduced a new method setIndicatorBoundsRelative(int, int) which works ok for 4.3.
public int GetPixelFromDips(float pixels) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
explvList.setIndicatorBounds(width-GetPixelFromDips(35), width-GetPixelFromDips(5));
} else {
explvList.setIndicatorBoundsRelative(width-GetPixelFromDips(35), width-GetPixelFromDips(5));
}
}
private void setGroupIndicatorToRight() {
/* Get the screen width */
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
expandableList.setIndicatorBounds(width - getDipsFromPixel(35), width - getDipsFromPixel(5));
}
// Convert pixel to dip
public int getDipsFromPixel(float pixels) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 250.5f);
}
If you want to move indicator to right Just create a dimen in res folder. It will be like that:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="my_value">350dp</dimen>
</resources>
Then in the <ExpandableListView/> add like that:
<ExpandableListView
...
android:indicatorLeft="#dimen/my_value"
.../>
You can change the dp according to device settings
Related
So I'm totally lost now I have problems with Text size ruing my UI when user sets his font size through Accessibility -> Font size to Huge so for quick fix I decided to change all text sizes to dp instead of sp that text would always be same size but on some places textviews even when textsize is set to dp resizes any idea why??
Here is button with text size set to dp which maintains font size even after changing through accessibility
<Button
android:id="#+id/video_button"
android:textSize="16dp"
android:layout_marginTop="10dp"
android:layout_height="30dp"
android:layout_width="180dp"
android:layout_centerHorizontal="true"
android:layout_below="#+id/webshop_button"
android:text="#string/button_3dvideo_text"/>
And here is textView which ignores textSize even after setting it to dp:
<TextView
android:id="#+id/about"
android:gravity="center"
android:textSize="16dp"
android:layout_above="#+id/footer"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/color_white"
android:text="#string/about"/>
I have a solution for this which will make the font size non changeable in your app :
public void adjustFontScale(Configuration configuration) {
configuration.fontScale = (float) 1;
DisplayMetrics metrics = getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.fontScale * metrics.density;
getBaseContext().getResources().updateConfiguration(configuration, metrics);
}
Call this method in onCreate of your every Activity or you can make a Base Activity:
adjustFontScale(getResources().getConfiguration());
You can change the fontScale according to your needs.
Hope this helps.
May be try to use this Not sure whether its going to help you.
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
float dp = 20f;
float fpixels = metrics.density * dp;
int pixels = (int) (fpixels + 0.5f);
Edit_click.setTextSize(pixels);
Question
I'm using the BottomSheetDialogFragment for my modal bottom sheet and would like to set a maximum width so that on tablets/large screens the BottomSheet doesn't occupy the entire width of the screen. How do I approach solving this? Thanks!
Relevant code & resources
fragment_bottomsheet.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="#style/BottomSheetStyle">
<GridLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alignmentMode="alignBounds"
android:columnOrderPreserved="false"
android:columnCount="3"
android:paddingTop="16dp"
android:paddingBottom="8dp"
android:paddingRight="8dp"
android:paddingLeft="8dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/image1"
android:text="Open"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/image2"
android:text="Save"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/image3"
android:text="Send"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/image4"
android:text="Upload"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/image5"
android:text="Share"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="#drawable/iamge6"
android:text="More"/>
</GridLayout>
</android.support.design.widget.CoordinatorLayout>
res/values/styles.xml:
<style name="BottomSheetStyle">
<item name="android:layout_height">match_parent</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_gravity">center_horizontal</item>
</style>
res/values-w600dp/styles.xml:
<style name="BottomSheetStyle">
<item name="android:layout_height">match_parent</item>
<item name="android:layout_width">640dp</item>
<item name="android:layout_gravity">center_horizontal</item>
</style>
I found a solution which works for me:
#Override
public void onResume() {
super.onResume();
// Resize bottom sheet dialog so it doesn't span the entire width past a particular measurement
WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
int width = metrics.widthPixels < 1280 ? metrics.widthPixels : 1280;
int height = -1; // MATCH_PARENT
getDialog().getWindow().setLayout(width, height);
}
Essentially this allows me to dynamically specify dimensions for my BottomSheet based on display.
A variation of the OP's answer that takes into consideration device's pixel density and orientation:
public final class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {
...
private static int dpToPx(int dp) {
// https://developer.android.com/guide/practices/screens_support.html#dips-pels
float density = Resources.getSystem().getDisplayMetrics().density;
return (int) ((dp * density) + 0.5f);
}
#Override
public void onResume() {
super.onResume();
Configuration configuration = getActivity().getResources().getConfiguration();
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&
configuration.screenWidthDp > 450) {
// you can go more fancy and vary the bottom sheet width depending on the screen width
// see recommendations on https://material.io/components/sheets-bottom#specs
getDialog().getWindow().setLayout(ViewUtils.dpToPx(450), -1);
}
}
}
As you mention, BottomSheetDialogFragment does not seem to respect "wrap_content" (it always matches parent on width, even if all the views it contains have a width of "wrap_content"). I found that the best workaround for me was to utilize OnGlobalLayoutListener to listen for the appropriate time to adjust the width. Example:
#Override
public void setupDialog(final Dialog dialog, int style) {
super.setupDialog(dialog, style);
View v = View.inflate(getActivity(), R.layout.my_bottom_sheet, null);
View viewWithGreatestWidth = v.findViewById(R.id.my_super_wide_view);
// Your view setup code goes here ....
if(getResources().getBoolean(R.bool.isTablet)) {
v.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
// Can also just use your own preset "max width" value here;
// This code just lets you fake "wrap_content" value
getDialog().getWindow().setLayout(viewWithGreatestWidth.getMeasuredWidth(), WindowManager.LayoutParams.WRAP_CONTENT);
}
});
}
dialog.setContentView(v);
}
If you want to do it purely in xml, you can set a style and use android:maxWidth
For example:
<LinearLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/white"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
style="#style/styleWithFixedWidth"
>
and in styles.xml
<style name="styleWithFixedWidth">
<item name="android:maxWidth">550dp</item>
</style>
Expandable Listview SetIndicatorBounds are not working in my project code.
Here is my Layout:
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|center_vertical"
android:weightSum="1.0"
>
<ExpandableListView
android:id="#+id/custom_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:dividerHeight="1dp"
android:layout_weight="1"
android:paddingBottom="0dp"
android:divider="#b5b5b5"
/>
</LinearLayout>
Here is my code :
lv1 = (ExpandableListView) findViewById(R.id.custom_list);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
lv1.setIndicatorBounds(width - GetPixelFromDips(50), width - GetPixelFromDips(10));
public int GetPixelFromDips(float pixels) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
My Moto G kitkat device width is 720 .
But setIndicatorBounds did not seems to be worked out in my Kitkat device .
Any help will be appreciated.
Thanks,
try this:
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
mListView.setIndicatorBounds(myLeft, myRight);
} else {
mListView.setIndicatorBoundsRelative(myLeft, myRight);
}
reference
A sprite on my android game is set to fall by 5 pixels every 100 milliseconds, this works fine the only problem is that the ImageView itself is only 53dp high, if I make it any bigger the image inside scales with it. Since the ImageView is only 53dp high the image disappears after 1100 milliseconds as it scrolls outside the boundaries of the imageview.
I need the layout height of the ImageView to fill_parent but I need the image to stay the same size instead of scaling with it, here's my current code:
<ImageView
android:id="#+id/blueman"
android:layout_width="0dip"
android:layout_height="53dp"
android:paddingRight="300dp"
android:layout_weight="0.03"
android:src="#drawable/fall" />
Thanks in advance :)
since you didn't give the full code of the layout, I'll make some assumptions...
you're talking about setting your sprite's height to the screen's height without scaling?
There should be a difference between your screen size (that is the root layout item) and the sprites in it. I guess you declared your layout as...:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?gameBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btTap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="14dp"
android:layout_marginTop="350dp"
android:background="#drawable/tap"
android:visibility="visible" />
<Button
android:id="#+id/btCellR1C1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="490dp"
android:layout_marginTop="155dp"
android:background="#drawable/cell_red" />
The only thing I had to cope with, was the scaling of my sprites depending on the device's resolution with such a method:
public static void scaleView(View view, int top, int left, int width,
int height) {
top = Math.round(top * scaleY);
left = Math.round(left * scaleX);
width = Math.round(width * scaleX);
height = Math.round(height * scaleY);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.height = height;
params.width = width;
params.topMargin = top;
params.leftMargin = left;
view.setLayoutParams(params);
view.setSoundEffectsEnabled(false);
}
Please give us more details to help you
Best regards
Serge
I download image and set it as a screen background dynamically using Imageview. I have tried ScaleType, to scale the image.
If image height is larger than width then ScaleTypes fitStart, fitEnd and fitCenter don't work. Android scale down the photo and fit it based on the height, but I see some extra blank space as part of the width.
I want to scale down the photo based on the width so that it fits the width and I don't care if there's some extra blank space as part of the height or if height is too long it is fine if it's going out of the view(if that's possible?).
ScaleType.XY scale the photo and fit everything in the ImageView and doesn't care about image height/weight ratio.
<ImageView
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitStart"
/>
I ended up using this code:
<ImageView
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/name"
/>
Make sure you set the image using src instead of background.
android:adjustViewBounds="true" does the job!
This elegant solution found here will work like a charm for you.
Basically you just have to create a small class that extends ImageView and simply override the onMeasure method to adjust the width and height as you want. Here it scales to fit width by using:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
setMeasuredDimension(width, height);
}
You would use this special ImageView like this:
<your.activity.package.AspectRatioImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:src="#drawable/test" />
There is a simple method if you simply want to fill the width of screen and have height proportional (and know the ratio of the image) you can do this in OnCreate():
setContentView(R.layout.truppview_activity);
trupImage = (ImageView) findViewById(R.id.trupImage);
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
float scWidth = outMetrics.widthPixels;
trupImage.getLayoutParams().width = (int) scWidth;
trupImage.getLayoutParams().height = (int) (scWidth * 0.6f);
Where 0.6 is the ratio adjustment (you could also calc automatically of course if you know the w & h of image).
PS:
Here is the XML side:
<ImageView
android:id="#+id/trupImage"
android:layout_width="match_parent"
android:background="#color/orange"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
if you want to fit the image whole parent block
it will stretch the image
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
And if you want to fit image whole parent with original ratio of image
it will crop out some part of image
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
This works for me.
Create a class extends ImageView
package com.yourdomain.utils;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
In xml use the following instead of ImageView
<com.yourdomain.utils.ResizableImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/test" />
I think you cant do it only with XML, you need to resize yourself, the bitmap
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
try {
((ImageView) findViewById(R.id.background))
.setImageBitmap(ShrinkBitmap(width));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
then
private Bitmap ShrinkBitmap(int width)
throws FileNotFoundException {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.img, bmpFactoryOptions);
int widthRatio = (int) android.util.FloatMath
.ceil(bmpFactoryOptions.outWidth / (float) width);
bmpFactoryOptions.inSampleSize = widthRatio;
if (bmpFactoryOptions.inSampleSize <= 0)
bmpFactoryOptions.inSampleSize = 0;
bmpFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.img, bmpFactoryOptions);
return bitmap;
}
And the layout
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>