I have to embed a button "inline" within a multiline textview, like so:
I'm not sure how to do this in Android, as there are no layout elements or attributes (that I'm aware of) that allow aligning a Button where text ends in a multiline TextView. And I really don't want to use a WebView for this and do it with html / css, as this screen is already heavy enough. Any ideas how to accomplish it?
ClickableSpan is the answer to your problem!
Android strings accept unicode and html characters, which includes arrows
You can create a textview(tvDescription) with the maxLines=5 and ellipsize=end
I'm assuming the maximum lines you wan to show is 5
android:ellipsize="end"
android:maxLines="5"
Add a view(btnIndicator currently button. You can change as per your requirements) which always stays on the bottom right of the textView. This view contains the text (View More and View Less). Suggest you to use constraint layout which will make your task easy.
Assuming you have got the reference to Textview as tvDescription.
And the view at the bottom right as btnIndicator. Add onClickListener to this view.
btnIndicator.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int maxLines = tvDescription.getLineCount();
if (maxLines == 5) {
maxLines = Integer.MAX_VALUE;
btnIndicator.setText("View Less")
}
else {
maxLines = 5;
btnIndicator.setText("View More")
}
/*
* Here you can append the text VIEW MORE(when max lines is 5)
* or ignore if it is already expanded
* */
tvDescription.setMaxLines(maxLines);
}
});
Related
I'm using ConstraintLayout with Flow Helper object in order to organize some buttons on the screen.
The buttons are not centering the text as it should.
I have the following button:
<Button
android:id="#+id/x"
android:layout_width="0dp"
android:layout_height = "0dp"
app:layout_constraintHeight_max="300dp"
app:layout_constraintHorizontal_weight="1"
android:layout_margin="1dp"
android:text="x909"
android:textSize="18sp"
android:gravity="center"
android:maxLines="1"
As you can see there are many values that will affect the size and positioning of the button upon rendering.
The button positioning is working fine. The problem is the text positioning inside the button.
So, in the button above the text:
x909 will show as ONLY an 'x' centered in the button, with maxLines = "1"
x909 shows as ONLY an 'x9' centered in the button , with maxLines = "2" , BUT the 9 shows below 'x'
x909 shows as ONLY an 'x90' centered in the button, with maxLines ="3" , BUT the x is on top, the 9 below it and the 0 below the 9
The text is broken up into its characters and somehow a newline character is placed between characters so it displays vertically from top to down. I'm using LTR orientation
I've tried many different combinations using textAlignment, maxLines, lines, minLines, all types of gravity but every time the text is broken up into its characters and displayed vertically.
Any suggestions
I was able to find the solution by guiding myself with an old project I had:
Inside the Fragment onViewCreated method which loads the ConstraintLayout, I create a ViewGroup object which sets up a ViewTreeObserver.OnGlobalLayoutListener object.
As the buttons are laid out, I change their singleLine attribute to true and even change the TypeFace of the text.
Here's the code: It works perfectly:
ViewGroup group = (ViewGroup)view;
final ViewGroup myGroup = group.getRootView().findViewById(R.id.graphlay);
if(myGroup!=null){
ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
for(int u = 0; u < myGroup.getChildCount(); u++){
View view01 = myGroup.getChildAt(u);
try{
Button button = (Button)view01;
Log.d("inspectme","button: " + button.getText());
button.setTypeface(MainActivity.typeface0024);
button.setSingleLine(true);
}catch (Exception exx){
}
}
myGroup.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
};
myGroup.getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
I still would like to know the way of doing this in the XML instead of creating a ViewTreeObserver.OnGlobalLayoutListener object!!
I have two TextViews next to each other inside ConstraintLayout. Each of them has two words.
The words inside of them can be changed by the current locale.
Currently each of them takes equally space on the width by using android:layout_weight="1" and android:layout_width="0dp"
If the text in any of them is too long to fit one line, I want both of them to expand to two lines. I need the text itself to be expanded, not the TextView - that can be done only if the text has at least two words.
Is there a way to do that?
You will need for layout to proceed then determine if the left TextView has two lines and, if it does, adjust the right TextView to also occupy two lines. The following code is one way to do this. You can place this in onCreate().
val layout = findViewById<ConstraintLayout>(R.id.layout)
layout.doOnNextLayout {
val textView1 = findViewById<TextView>(R.id.textView1) // Left view
val textView2 = findViewById<TextView>(R.id.textView2) // Right view
if (textView1.lineCount == 2) { // If left view has 2 lines, add newline to the right view.
textView2.text = textView2.text.toString().replace(" ", "\n")
}
}
I have created a custom UI in Android Studio which inherits from LinearLayout. Essentially, it is an edit text with a blue semi-rounded rectangle in it that text can be placed in.
I've added an enum property called borderSide which has the values right and left. By default, the border is on the right. What I'm trying to do is have a condition that when borderSide is left, a different layout is selected so the blue semi-rounded rectangle is on the left. Having searched around, I can't see any simple way to do this.
Currently, I have this (apologies if it's a bit messed up, it's on a different machine)
In drawable, I have two files; supplemental_edittext and supplemental_edittext_left. These are selectors for the different pressed, enabled and focus states and select a drawable. Left means it selects the drawable set for the left side of the edittext. The drawable sets up the border and the rectangle.
The base class (ValidLayout) for the layout inherits LinearLayout, and has a couple of properties for error text. It also inflates a simple layout which contains two text views for a title and the error text. It has an edittext widget in which is added in #override public void addView - it looks like this
#Override
public void addView(View child, int index, ViewGroup.LayoutParams params)
{
if (child instanced EditText)
{
if (editText != null)
throw new RuntimeException("You can only add 1 child");
editText = (EditText) child;
super.addView(child, 1, params);
}
else
{
super.addView(child, index, params);
}
}
The class I've set the borderSide property in (SupplementEditText) extends from the base class and has a method in called setBorderSide(int side). There is a test for edittext (created above) which first checks if it's null and if it isn't sets the background. The code for the change looks like this
public void setBorderSide(int side)
{
if (edittext == null)
return;
borderSide = side == 0 ? false : true;
editText.setBackgroundResource(borderSide ? R.drawable.supplemental_edittext : R.drawable.supplemental_edittext_left);
}
The initial call to setBorderSide is made in the Initialise method.
Together in xml, they work like this
<ValidLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/vlEditText"
app:borderSide="left">
<SupplementEditText
android:layout_width="match_content"
android:layout_height="wrap_content"
android:id="#+id/sEditText"
app:supplementTextPosn="end"
app:supplementText="Hi" />
supplementTextPosn and supplementText are two properties in SupplementText that sets the text and text position at the left or right of the EditText inside of the semi rounded rectangle created in the base class
There seems to be two problems though. Firstly (and this is probably the big on), edittext is null. If I remove the check though, the border remains always on the left irrespective of what I set borderSide to.
In AndroidStudio, is there a way to test what is going on and why it's misbehaving and more over, a way to swap from supplemental_edittext to supplemental_edittext_left
So I have two TextViews in a RelativeLayout in my xml file. When they are localized to different languages, there will be a chance that the two views will overlap with each other.
In this case I want to put them into two lines instead of just one line. How to detect the overlap and reset their position so on is on top of the other in java code?
I did this with a LinearLayout and by using the textview's auto wrap feature Iwas able to detect if the textview wrapped. By using a ViewTreeObserver and looking at the number of lines for the textview I then programmatically set the view to Gone.
final TextView text = findViewById(R.id.textview1);
text.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int lineCount = text.getLineCount();
Log.d(this, "LineCount = " + lineCount);
if (lineCount > 1) {
text.setVisibility(View.GONE);
}
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
Just have to make sure your layouts don't ellipsize or that you set the singleLine or Maxlines to true or 1. I set Max line on the one textview I want gone to 2 so that it will wrap if it won't fit.
Just put your layout in a language spefic layout folder.
Your standard layout in res/layout
another in res/layout-ar (example for arabic)
Friends,
I have 3 text views in a LinearLayout which has a bounded width of 300dp. Each text view has a layout_weight of 1 so the screen will be divided evenly among the three TextViews.
[text view 1][text view 2][text view 3]
Most of the time the text fits in one line in each of the TextView but there are some occasion when it does not. Is there any way I could determine that the Text will need two lines and set the number of lines parameter of the TextView to 2?
If one of the TextViews needs 2 lines than all three TextViews should be set to two lines
The short answer is yes- TextView has a getLineCount() method that will tell you how many lines of text are the TextView.
Unfortunately there's a caveat- the TextView must be layed out and measured before this method works properly.
If you are setting the text dynamically (e.g. via setText()), then you will need to create a callback for when the layout pass happens like so:
mTextView1.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (mTextView1.getLineCount() > 1) { // or textView2, etc.
// Adjust all text view heights
}
}
});