Android: how to get value of "listPreferredItemHeight" attribute in code? - android

The below code gives Resources$NotFoundException
TypedValue value = new TypedValue();
((Activity)context).getResources().getValue(android.R.attr.listPreferredItemHeight, value, true);
EDIT: More code added in response to answer.
When I run the below code, all members of displayMetrics are 0. As is ret.
TypedValue value = new TypedValue();
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);
float ret = value.getDimension(displayMetrics);

This works:
TypedValue value = new TypedValue();
((Activity)context).getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);
EDIT: You get zero because haven't initialized the DisplayMetrics instance properly. It needs a frame of reference (a display) to do any meaningful conversion.
android.util.TypedValue value = new android.util.TypedValue();
boolean b = getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);
String s = TypedValue.coerceToString(value.type, value.data);
android.util.DisplayMetrics metrics = new android.util.DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float ret = value.getDimension(metrics);
On my Nexus 1 s is 64.0dip and ret is 96.

Another answer
public float getItemHeight() {
TypedValue value = new TypedValue();
DisplayMetrics metrics = new DisplayMetrics();
context.getTheme().resolveAttribute(
android.R.attr.listPreferredItemHeight, value, true);
((WindowManager) (context.getSystemService(Context.WINDOW_SERVICE)))
.getDefaultDisplay().getMetrics(metrics);
return TypedValue.complexToDimension(value.data, metrics);
}
it maybe more useful.

Femi's answer was very helpful. Without wanting to detract from his answer, I've taken the logic and placed it in a library convenience method that you should be able to plug-and-play. I plan on updating the code with other attribute methods over time. I hope it proves useful to someone.
(Note that I discovered Resources.getDisplayMetrics() seems to be an easier way to return display metrics rather than querying the WindowManager.)

The shortest answer (without DisplayMetrics):
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, typedValue, true);
int height = TypedValue.complexToDimensionPixelSize(typedValue.data, context.getResources().getDisplayMetrics());

Related

How to express, in java, a textsize to be accepted in different resolutions?

To get the dimensions of each particular device, I have written this code:
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) MainActivity.this.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
windowManager.getDefaultDisplay().getMetrics(metrics);
}
int ancho = metrics.widthPixels;
int alto = metrics.heightPixels;
However, when I play with this dimension (for example: ...setTextSize (ancho/45)), it shows different sizes in different resolutions. Could you help me to solve this problem? In XML, using different layouts, I can work ir out using different sizes (for example: android:textSize="16sp"/"20sp"/"24sp"...), but not in JAVA.
Do it like this:
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
Thinking a lot about it, and searching for information in other places in the forum, I got the correct solution:
float SCREEN_DENSITY = getResources().getDisplayMetrics().density;
my_textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, (desiredTextHeightInSP / SCREEN_DENSITY));
My "desiredTextHeightInSP" and "my_textView" in my above problem were "btnTag" and "ancho/45".

Dynamically change editTexts position based on screen Size / DPI

I would like to change the position of one element (editText) in my UI when the user taps it. The positioning should be ~20 dp under the actionBar, no matter screen-size or DPI the device is using.
How do I accomplish this using only (java)code? Please try to give a more exact answer. I have seen other examples similar to this but none that explains an exakt scenario? I was thinking of a start like the code below? Then what?:
DisplayMetrics dm = new DisplayMetrics();
mSearchField = (EditText)v.findViewById (R.id.something);
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int [] loc = new int[2];
mSearchField.getLocationOnScreen(loc);
int distance = dm.heightPixels - loc[1];
Get the Display height and width using DisplayMetrics.
DisplayMetrics displayMetrics = new DisplayMetrics();
mContext.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
Log.e("width",width+""+height);

Reference different raw resource depending on screen orientation

I would like to define raw resources in my dimens.xml file like I define margins, padding for different screen orientations.
I've tried this:
<item name="my_res" type="raw" format="string">R.raw.test</item>
But that doesn't seem to be working.
When I try to fetch id of that resource, it is not correct:
TypedValue out = new TypedValue();
getResources().getValue(R.raw.my_res, out, true);
int resId = out.resourceId;
Any suggestions how to han
Use Activity.getResources().getConfiguration().orientation for obtaining ORIENTATION_PORTRAIT and ORIENTATION_LANDSCAPE values indicating current orientation. Based on this, get appropiate raw resource.
TypedValue out = new TypedValue();
int resId;
if(Activity.getResources().getConfiguration().orientation == 1) { //1 for Portrait and 2 for Landscape
getResources().getValue(R.raw.my_res, out, true);
resId = out.resourceId;
} else {
getResources().getValue(R.raw.my_res_alternate, out, true);
resId = out.resourceId;
}
Do any necesary change, but this is the main idea.

get dimension of displayable area of android device

I actually have two code snippets that I need to compare. Which one is more accurate? I am looking for the dimension of the drawable surface of a device.
Code 1:
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int result[] = { metrics.heightPixels, metrics.widthPixels };
Code 2:
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
I need one for using inside a class that extends View
getSize() was introduced in API level 13. If you want to support API levels before that you should use your first option. In a view you can use it like:
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);‌​
int result[] = { metrics.heightPixels, metrics.widthPixels };
Otherwise There is no difference in accuracy

Android: how to get value of an attribute in code?

I would like to retrieve the int value of textApperanceLarge in code. I believe that the below code is going in the right direction, but can't figure out how to extract the int value from the TypedValue.
TypedValue typedValue = new TypedValue();
((Activity)context).getTheme().resolveAttribute(android.R.attr.textAppearanceLarge, typedValue, true);
Your code only gets the resource ID of the style that the textAppearanceLarge attribute points to, namely TextAppearance.Large as Reno points out.
To get the textSize attribute value from the style, just add this code:
int[] textSizeAttr = new int[] { android.R.attr.textSize };
int indexOfAttrTextSize = 0;
TypedArray a = context.obtainStyledAttributes(typedValue.data, textSizeAttr);
int textSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
a.recycle();
Now textSize will be the text size in pixels of the style that textApperanceLarge points to, or -1 if it wasn't set. This is assuming typedValue.type was of type TYPE_REFERENCE to begin with, so you should check that first.
The number 16973890 comes from the fact that it is the resource ID of TextAppearance.Large
Using
TypedValue typedValue = new TypedValue();
((Activity)context).getTheme().resolveAttribute(android.R.attr.textAppearanceLarge, typedValue, true);
For the string :
typedValue.string
typedValue.coerceToString()
For other data :
typedValue.resourceId
typedValue.data // (int) based on the type
In your case what it returns is of the TYPE_REFERENCE.
I know it should point to TextAppearance.Large
Which is :
<style name="TextAppearance.Large">
<item name="android:textSize">22sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">?textColorPrimary</item>
</style>
Credit goes to Martin for resolving this :
int[] attribute = new int[] { android.R.attr.textSize };
TypedArray array = context.obtainStyledAttributes(typedValue.resourceId, attribute);
int textSize = array.getDimensionPixelSize(0, -1);
Or in kotlin:
fun Context.dimensionFromAttribute(attribute: Int): Int {
val attributes = obtainStyledAttributes(intArrayOf(attribute))
val dimension = attributes.getDimensionPixelSize(0, 0)
attributes.recycle()
return dimension
}
It seems to be an inquisition on the #user3121370's answer. They burned down. :O
If you just need the get a dimension, like a padding, minHeight (my case was: android.R.attr.listPreferredItemPaddingStart). You can do:
TypedValue typedValue = new TypedValue();
((Activity)context).getTheme().resolveAttribute(android.R.attr.listPreferredItemPaddingStart, typedValue, true);
Just like the question did, and then:
final DisplayMetrics metrics = new android.util.DisplayMetrics();
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
int myPaddingStart = typedValue.getDimension( metrics );
Just like the removed answer. This will allow you to skip handling device pixel sizes, because it uses the default device metric. The return will be float, and you should cast to int.
Becareful to the type you are trying to get, like resourceId.
this is my code.
public static int getAttributeSize(int themeId,int attrId, int attrNameId)
{
TypedValue typedValue = new TypedValue();
Context ctx = new ContextThemeWrapper(getBaseContext(), themeId);
ctx.getTheme().resolveAttribute(attrId, typedValue, true);
int[] attributes = new int[] {attrNameId};
int index = 0;
TypedArray array = ctx.obtainStyledAttributes(typedValue.data, attributes);
int res = array.getDimensionPixelSize(index, 0);
array.recycle();
return res;
}
// getAttributeSize(theme, android.R.attr.textAppearanceLarge, android.R.attr.textSize) ==> return android:textSize

Categories

Resources