19

I’m trying set a layout for textview so I can use getEllipsisCount() method. But below code returns null as layout value. How can I take layout and then use getEllipsisCount(0) method.

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView mytextview =(TextView) findViewById(R.id.textView1);
        mytextview.setText(myText);
    
        Layout layout = mytextview.getLayout();
        if(layout != null){
            mytextview.setText("very good layout worked\n");
        }
    }
}
mgarciaisaia
  • 14,521
  • 8
  • 57
  • 81
Soroush Aghaiee
  • 193
  • 1
  • 1
  • 4

6 Answers6

40

You are calling it too early, thats why it is returning null

Try this

  ViewTreeObserver vto = mytextview.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
           Layout layout = mytextview.getLayout();  
        }
    });
Pragnani
  • 20,075
  • 6
  • 49
  • 74
  • 4
    It's worth noting that getLayout can still return null even inside onGlobalLayout. You'll need to figure out how to deal with this in your code, unfortunately. –  Apr 23 '14 at 19:27
  • 12
    I found a way around the fact that getLayout() might be null even after global layout: I use addOnPreDrawListener() instead and listen by returning true until getLayout() starts to return true and only then I use it, call removeOnPreDrawListener() and return false from this pre draw listener to cause a relayout – dimsuz Aug 04 '15 at 13:28
5

From the documentation:

public final Layout getLayout ()

Added in API level 1 Returns the Layout that is currently being used to display the text. This can be null if the text or width has recently changes.

So probably your text has changes or you call it too early.

Look at this answer where is stated

This only works after the layout phase, otherwise the returned layout will be null, so call this at an appropriate place in your code.

Community
  • 1
  • 1
gipi
  • 2,432
  • 22
  • 25
5

Call

TextView.onPreDraw();

It creates the layout.

Joren
  • 3,068
  • 25
  • 44
Wonsik Sung
  • 61
  • 1
  • 2
1

I recently encountered this problem myself. For any newcomers to this thread, the accepted answer by @Pragnani along with the comment from @dimsuz provides a nice and compact solution. Adding an OnPreDrawListener to the view tree of the text view, wait for a reference to a layout and use it, and lastly remove the listener after any work requiring the layout is finished.

Given the example code from OP, implementing the solution could look something like this:

public class MainActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {

    // maintain a reference to the view so we can later remove the listener
    private TextView mytextview;

    @Override
    public boolean onPreDraw() {
        Layout layout = mytextview.getLayout();
        if (layout != null) {

            // use layout here...
            int n = layout.getEllipsisCount(0);

            // work requiring a layout is finished; remove listener from view
            mytextview.getViewTreeObserver().removeOnPreDrawListener(this);
        }
        return true;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mytextview = (TextView) findViewById(R.id.textView1);

        // add listener to the view
        mytextView.getViewTreeObserver().addOnPreDrawListener(this);
    }
}
Adam Martinu
  • 253
  • 1
  • 11
0

Call mytextview.getLayout() in onStart or onResume callback.

tomrozb
  • 25,773
  • 31
  • 101
  • 122
pskink
  • 23,874
  • 6
  • 66
  • 77
-1

First, I do not know if it is a typo or it is intentional but you have declared a "settext" method instead of the predefined setText. However to get a reference of your layout I suggest you the following:

LayoutInflater inflater = getLayoutInflater();

RelativeLayout textViewLayout = (RelativeLayout) inflater.inflate(R.layout.activity_main,null);

if (textViewLayout != null) {
    mytextview.setText("very good layout worked\n");
}

supposing that your TextView belongs to a RelativeLayout.

Victor Laerte
  • 6,446
  • 13
  • 53
  • 102
r4m
  • 491
  • 4
  • 14