2

How can I get line number form a string?
Suppose I have a string like this

String testString  = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis p";

And also I have a view that will show the string. In a different case, I want to get the line number first before rendering.
I want to get the line number from this string in Android. I got several ways to get the line number. But In every solution, we can get the line number after view rendering. But I want it before rendering of the view. I want to get the line number for 20 or more different strings.
How can I get this any idea?

Faysal Ahmed
  • 7,501
  • 5
  • 28
  • 50
  • 1
    Do you mean to say the 'count of how many lines' ? – JGPhilip Feb 08 '18 at 09:54
  • 2
    your question is unclear – Zaid Mirza Feb 08 '18 at 09:55
  • 1
    what is that you want? please clear – Abdul Kawee Feb 08 '18 at 09:56
  • 1
    obviously you can't get line no before rendering . different device has different screen resolution – Tejas Pandya Feb 08 '18 at 09:56
  • @AbdulKawee please see the update. – Faysal Ahmed Feb 08 '18 at 10:02
  • 2
    Your question is worded strangely. Your string is clearly a single line, unless you want to cut it up by the commas. Do you mean show line numbers on your Android View after you've shoved your string in there? At any rate, Views are assigned a size when they are rendered and to my knowledge there is no way to do get it beforehand. What could be done is render it, get the size, then alter the view based on the data afterward. I think there's a hook like onPostCreate somewhere? Check out the activity lifecycle. – G_V Feb 08 '18 at 10:26
  • Why you want to get the line number first before rendering ?? – Upendra Shah Feb 16 '18 at 12:58
  • 1
    there is no way to get it before rendering but just compile several times and save the number of chars in each line as a constant and get your string chars and divide them. note that in this case you have to do this in every screen size just tell us why you need that maybe we come up with better solution . – Pouya Danesh Feb 17 '18 at 07:13
  • Do you have a long text and you want to find the number of this line in different devices? – nima barati Feb 17 '18 at 10:51

6 Answers6

9

The line break calculation occures on layouting. Therefore:

findViewById(R.id.myTextView).addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            int lineCount = ((TextView)v).getLayout().getLineCount();
        }
});
artkoenig
  • 7,117
  • 2
  • 40
  • 61
6

Try this code:

Rect bounds = new Rect();
Paint paint = new Paint();
paint.setTextSize(textSize);
paint.getTextBounds(str, 0, str.length(), bounds);    
int linesCount = (int) Math.ceil((float) bounds.width() / textSize);

This works before rendering of view.

Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45
  • 1
    The answer this is copied from @ https://stackoverflow.com/a/15679207/461982 is a bit misleading. You are taking the width of your total text and dividing it by the width of one line, which would give you the number of lines. It is incorrectly labeled as `int width`, which led to much of the confusion in the comments. – Abandoned Cart Apr 08 '18 at 00:23
5

You can use a android.text.Layout, or more specifically a android.text.StaticLayout. It's not a ViewGroup but a class used by views like TextView to manage the text layout. It can give you a lot of information about the (text) layout, like the position of each line, or conversely the offset in the text of a specific line.

Obviously it needs to know the available width, so unless you know it beforehand (e.g. your text uses the whole screen width) you still have to wait for a (view) layout.

float density =  getResources().getDisplayMetrics().density;

// information about the font
TextPaint paint = new TextPaint();
paint.setTextSize(18 * density);

int width = (int) (300 * density);
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;

StaticLayout layout = new StaticLayout(text, paint, width, alignment, 1, 0, false);

int lines = layout.getLineCount();
Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
bwt
  • 17,292
  • 1
  • 42
  • 60
3

Not sure I understand your question entirely. But you could try using reflection to get line number of the method that wraps it.

Method m; // the method object
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(m.getDeclaringClass().getCanonicalName());
CtMethod javassistMethod = cc.getDeclaredMethod(m.getName());
int linenumber = javassistMethod.getMethodInfo().getLineNumber(0);

Could probably modify this for variables as well. Not sure if that solves your issue, or even what you are trying to do lol, but once compiled, getting line numbers is not as easy as reading raw files especially if you enable obfuscation.

Sam
  • 5,342
  • 1
  • 23
  • 39
0

After searching finally I have got a solution that will take some time but my actual problem is solved.

 public void getTotalLineNumber() {

        RelativeLayout linearLayout = findViewById(R.id.layout_constraint);
        textHeight = 0;
        for (int i = 0; i < stringList.size(); i++) {
            final TextView tv = new TextView(this);
            tv.setText(stringList.get(i));
            tv.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
            tv.setTextSize(15);
            tv.setTypeface(tv.getTypeface(), Typeface.BOLD);
            tv.setVisibility(View.INVISIBLE);
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) tv.getLayoutParams();
            params.setMargins(8, 5, 16, 5); //substitute parameters for left, top, right, bottom
            tv.setLayoutParams(params);
            linearLayout.addView(tv);

            tv.post(new Runnable() {
                @Override
                public void run() {
                    textLineCount += tv.getLineCount();
                }
            });
        }
    }

Finally, I have got the total line number from postHandler.

    getTotalLineNumber();
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            int totalLine = textLineCount;
             // Here I have got the line number.
        }
    }, 1000);

textLineCount is a global variable. It will take some time but works for me.

Faysal Ahmed
  • 7,501
  • 5
  • 28
  • 50
  • 1
    Your question states you wanted to get the line number of a given string before it was rendered and the answer you posted (and accepted) is how to get the overall line count of multiple views *after* they are rendered. It would have been impossible for anyone to provide a method to accomplish this based on your question. – Abandoned Cart Apr 08 '18 at 00:15
-2
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Get the widgets reference from XML layout
    mTextView = (TextView) findViewById(R.id.tv);
    // Get TextView Line numbers
    int lines = mTextView.getLineCount();
    //your other code
}
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37