3

I used TextView#getMaxLines() in my application for a few weeks without incident.

Lint is now informing me that it's only available in API 16+ (#setMaxLines() is API 1+...), though (to the best of my knowledge) I haven't modified anything that would cause this sudden flag - my min-sdk has been 8 for a while, and I have files in my source control to prove it.

1) Why could lint be flagging this error randomly? (To be clear, I mean to say that it should have caught it initially - I'm not implying this is something that it shouldn't have flagged at all).

2) Is there any way to retrieve the maxLines for a TextView on pre-api 16 devices? I checked the source but couldn't devise a way to retrieve this value using the exposed methods on a 2.2 device.

ataulm
  • 15,195
  • 7
  • 50
  • 92

3 Answers3

26

A simpler solution was added to the support lib v4 inTextViewCompat

int maxLines = TextViewCompat.getMaxLines(yourtextView);

Check out this answer for some more informations.

Community
  • 1
  • 1
daemmie
  • 6,361
  • 3
  • 29
  • 45
4

You can use Reflection:

Field mMaximumField = null;
Field mMaxModeField = null;
try {
    mMaximumField = text.getClass().getDeclaredField("mMaximum");
    mMaxModeField = text.getClass().getDeclaredField("mMaxMode");
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

if (mMaximumField != null && mMaxModeField != null) {
    mMaximumField.setAccessible(true);
    mMaxModeField.setAccessible(true);

    try {
        final int mMaximum = mMaximumField.getInt(text); // Maximum value
        final int mMaxMode = mMaxModeField.getInt(text); // Maximum mode value

        if (mMaxMode == 1) { // LINES is 1
            text.setText(Integer.toString(mMaximum));
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

OR:

Maybe, the best way is keep maxLine value at values and set it value in xml, and get as int resource in code.

nfirex
  • 1,523
  • 18
  • 24
  • 1
    I agree with your "But, maybe" part, and this is how I was planning to work around the issue. I don't think there's any point using reflection because I wouldn't have been able to handle pre-API 16 devices without manually keeping track of the values *in addition* to using `getMaxLines()` for API16+ (in which case it would make the latter redundant). – ataulm Apr 27 '13 at 20:11
  • ah wait, I think I entirely misunderstood. (If you remove the bulletpoint markup, it fixes your code formatting for SO.) If `mMaximum` is private, would it still get the correct value at the time of the call? – ataulm Apr 27 '13 at 20:15
  • @ataulm for getting private field value you just need to set Field.setAccessible(true). Sorry for the poor formatting:( – nfirex Apr 27 '13 at 20:46
  • Hi, I am trying to use reflection technique but getDeclaredField() returns null and causes exception right away even though the class includes those variables. Any ideas? – ahmad Dec 02 '14 at 21:40
  • @ahmad, do you use reflection in this class and on this fields? or it is not working in another class? – nfirex Dec 03 '14 at 08:35
  • I figured it out, if you use view.getClass() it returns null but if I use TextView.class it works perfectly. I am not sure why this is the case, maybe someone can shed some light on it but the code works great! – ahmad Dec 03 '14 at 17:00
  • @ahmad , I think that this link (http://stackoverflow.com/a/10947795/1001401) may shed light :) – nfirex Dec 04 '14 at 09:11
  • Anyone knows the reason for the issue that ahmad comments? I think nfirex's code should work even for `TextView` subclasses... Thanks! – Ferran Maylinch Jul 08 '15 at 15:02
1

The code for that method simply doesn't exist on 2.2, so you can't use it directly of course.

On the other hand, I've run a diff on the two files and it seems as though the new 4.2.2 TextView isn't using any new APIs internally (this is based solely on its imports). You may be able to add it as a class in your project and use it instead of the inbuilt TextView across all version of Android.

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
  • I was actually planning on subclassing `TextView` anyway so I could specify fonts in XML, so this sounds like a good idea. I suppose there would be minimal overhead with adding this as a class in my project? (And even no difference in performance at all if I subclassed the 4.2.2 TextView (after including it) instead of the 2.2 one?) +1 for the preliminary check for compatibility, I'll include it and test it on an API8 emulator. – ataulm Apr 27 '13 at 19:14
  • I was unable to include the new version directly; a lot of the imports couldn't be resolved. I tried also with copying the 2.2 TextView class, and the same imports couldn't be resolved (e.g. `import android.content.res.CompatibilityInfo;`) – ataulm Apr 27 '13 at 20:29