0

I like to add a control in my app. The specialty of the control is it contain multiple lines of text (eg 5 lines) and does not contain a scrollbar. I will explain through the below example.

|-----------------|
| text1           |
| text2           |
| text3           |
| text4           |
|                 |
|-----------------|

if you add a string to text view it will became

|-----------------|
| text1           |
| text2           |
| text3           |
| text4           |
| text5           |
|-----------------|

if you add another line of text it will became

|-----------------|
| text2           |
| text3           |
| text4           |
| text5           |
| text6           |
|-----------------|

Is it possible? I googled, but couldn't find a solution.

Lance Roberts
  • 22,383
  • 32
  • 112
  • 130
Riskhan
  • 4,434
  • 12
  • 50
  • 76

3 Answers3

1

If you wanted it to be a re-usable control, you would need to write a custom view for this which you can add text to and internally it shifts the text between the inner TextViews.

Alternatively you can just use multiple TextViews and copy the text from one to the other when you want to add a new line.

The functionality is not included as standard.

Kuffs
  • 35,581
  • 10
  • 79
  • 92
1

I don't know why you might want to have multiple lines without a scrollbar, but if that's what you need I think this might be a possible solution.

Obviously you will need some logic done onto your layout, because I can't think of a view that will give you this service without tweaking it some.

So, I'm thinking a RelativeLayout with 5 TextViews (the number of textViews depends on how many lines you want to show).

So each textView is going to contain one of your lines, so that when the user adds a new line you'd have to do something along these lines:

if( linesInView == 5 )
    shiftText();

addText();

So that shiftText() would be in charge of going through a loop and setting the text of one textView to another (shifting them), in order to make space for the new text.

Then addText() would just add the new text created by the user onto the freed spot generated thanks to shiftText().

All in all you could follow these guidelines. Keep in mind that I have just written this code out of the top of my head, I don't have means to check its correctness at the moment. Also, this is a first try, there's room for improvement:

private static int MAX_NUM_LINES = 5;
private int linesShown = 0;
private ArrayList<TextView> views = new ArrayList<>();
private EditText userInput;

public void onCreate(...){
   ....
   views.add((TextView)findViewById(R.id.firstline);
   views.add((TextView)findViewById(R.id.secondline);
   views.add((TextView)findViewById(R.id.thirdline);
   views.add((TextView)findViewById(R.id.fourthline);
   views.add((TextView)findViewById(R.id.fifthline);

   this.userInput = (EditText) findViewById(R.id.input);
  //I suggest these in order to avoid calling "findViewById()" everytime the user 
 // adds a new sentences, which I gather will happen often
}

public void someEventCalledWhenUserAddsNewLine(View view){
    if(this.linesShown>=MAX_NUM_LINES)
          shiftText();

    addNewLine();        
}

   private void shiftText(){
       //Shift your text by looping through your this.views
       for(pos=0; pos<this.views.size()-1; ++pos){
           String nextLine = this.views.get(pos+1).getText();
           this.views.get(pos).setText(nextLine);
       }
       //You need to set the condition to this.views.size()-1 because
      //when you reach position 4 (your last TextView) you have to sop
      // since there is not text to shift to that one
      this.views.get(this.views.size()-1).setText(null);
      //Make sure you set the text of the last TextView to null so that
      // addLine() will be able to find the first available TextView
   }

   private void addNewLine(){
      //Add text from this.userInput to the first available TextView in this.views
      int pos;
      for(pos=0; pos<this.views.size(); ++pos){
           if(this.views.get(pos).getText()==null){ 
              //We have found the first available TextView
                   break;
           }
      }  
      this.views.get(pos).setText(this.userInput.getText()); 
      //Pos holds the position of the first available TextView, now we have
      // added the new line  
     this.linesShown++;         
   }

Top of the bat improvement would be to just keep track of the index of the first available TextView so you don't have to mess with the loop in addLine() looking for it.

Chayemor
  • 3,577
  • 4
  • 31
  • 54
1

Something like that should work i guess, but i doubt if it's optimal:

public class LinesTextView {
    private TextView tv;
    private int linesCount = 0;
    private int maxLines = 5;
    public LinesTextView(TextView tv){
        this.tv = tv;
    }
    public void addLine(String line){
        if(linesCount == maxLines){
            String lines = tv.getText().toString();
            int pos = lines.indexOf("\n");
            StringBuffer buff = new StringBuffer(lines.substring(pos+1));
            buff.append('\n');
            buff.append(line);
            tv.setText(buff.toString());
        } else if(linesCount == 0){
            tv.setText(line);
            linesCount = 1;
        } else {
            StringBuffer buff = new StringBuffer(tv.getText().toString());
            buff.append('\n');
            buff.append(line);
            tv.setText(buff.toString());
            linesCount++;
        }
    }
}
alxio
  • 128
  • 4