17

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);
ab11
  • 19,770
  • 42
  • 120
  • 207

4 Answers4

32

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.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • Thank you, this does not give an exception. However, I still can't get the value of the attribute. I updated my question to reflect this. – ab11 May 12 '11 at 18:33
  • how do I get int of value 64 from TypedValue? I can't find a way to do that except parsing String from coerceToString. – Juozas Kontvainis Nov 23 '11 at 11:03
  • Ah, found it! TypedValue.complexToDimensionPixelSize(value.data, metrics) – Juozas Kontvainis Nov 23 '11 at 11:46
  • How can you parse the attribute from an extended class like `LinearLayout`? It seems I don't have access to `getTheme()` and trying `context.getResources().getValue(R.styleable.my_attr, value, true);` throws a `ResourcesNotFound` – Snailer Oct 05 '12 at 23:01
  • Note that in the above, this is called from the constructor `public Foo(Context context, AttributeSet attr)` – Snailer Oct 05 '12 at 23:02
  • An easier way to get display metrics if you have a context or are inside a fragment is by doing: `getResources().getDisplayMetrics()` or `Context.getResources().getDisplayMetrics()` – idunnololz Feb 06 '14 at 21:54
10

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.

kewang
  • 464
  • 7
  • 15
8

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.)

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
  • I found only Resources.getSystem().getDisplayMetrics(); for current Android version (4.4). – ATom Sep 06 '14 at 07:53
2

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());
user1185087
  • 4,468
  • 1
  • 30
  • 38
  • What happens if u remove the android prefix `resolveAttribute(R.attr.listPreferredItemHeight, typedValue, true);`? – user1185087 May 10 '17 at 20:27