Changing a layout depending on a property in android - android

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

Related

Button inside Android ConstraintLayout refuses to show multi-character text centered in horizontal orientation

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!!

How to display a Button inline within a multiline TextView

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);
}
});

How to change the color of the text inside a View?

I have some Views in my Activity that I inflate and populate at runtime.
The View itself is a RelativeLayout to which I add at runtime several TextViews.
When the View is selected I change the color of the background (and that is easy).
Now I need to change the color of all the TextViews inside the View.
Please how do I do that?
Consider that I do not have a reference to the TextViews themselves, since they are created at runtime, nor do I know how many are in there.
Consider that I do not have a reference to the TextViews themselves
Since you "add at runtime several TextViews", you are certainly welcome to "have a reference to the TextViews themselves". Add them to some sort of collection (e.g., ArrayList<TextView>) at the time when you "add at runtime", then iterate over the collection to change their color.
You can do this another way:
Iterate over all children of the RelativeLayout (which you have a reference to):
for (int i = 0; i < mRelativeLayout.getChildCount(); i++) {
if (mRelativeLayout.getChildAt(i) instanceof TextView) {
// Set text color
((TextView)(rl.getChildAt(i))).setTextColor(Color.RED);
}
}
Be careful about mRelativeLayout.get(i) instanceof TextView. This will return true for all Views returned by mRelativeLayout.getChildAt(i) that are subclasses of TextView. For example, if you have a Button inside mRelativeLayout, instanceof will return true since Button extends TextView. To avoid this, use:
if (mRelativeLayout.getChildAt(i) instanceof TextView &&
!(mRelativeLayout.getChildAt(i) instanceof Button))

Explain this android:orientation:"vertical"

What is android here?
what is Orientation here?
What is Vertical ?
I would be pleased to know if they are classes or packages or methods..?
I am confused?
Can some one explain hierarchy of it?
I am sure you have seen this inside the <LinearLayout>.
It means that whatever view you take inside the LinearLayout will be shown in screen by vertical (like Stake of views).
Every attributes started with android followed by : so here orientation is an attribute and vertical is the value to be assigned this attribute.
Update:
(Answer taken from here.)
For android:orientation="vertical", your views get stacked vertically like this:
View1
View2
View3
View4
etc...
And For android:orientation="horizontal", your views gets placed horizontally like this:
View1 View2 View3 View4 etc...
This is the XML tag for the Layout properties of any Layout Widget for Android UI.
android:orientation is the XML tag and "vertical" is value for the same. so when it will be loaded in UI framework, child of the layout will be arranged in vertical form.
These are Input parameters for XML tags . Although Java is an object oriented language ,but it does not means that you will consider every element of android as Classes . XML Layout structure is view forming technique which use native kit internally .so these #android:something are just identifier to tell the native kit what to do . nothing else .
This is the code written in android.widget.LinearLayout.java
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mOrientation == VERTICAL) {
layoutVertical();
} else {
layoutHorizontal();
}
}
You can view the SOURCE CODE HERE, Based on the orientation and gravity attribute how the android sets Child Views into Parent.

pop-up type view (z-index?) - android

I want to add a new view to my scene that will contain content that will change programatically throughout the course of my application. When it does change, it needs to pop up on the screen for 3 seconds (or a click) then disappear.
This view will change in size according to its content WRAP_CONTENT, but ideally I'd like it centered horizontally and vertically on the screen.
I'm stuck on three parts:
1) what type of view should I use for this...I was thinking Relative, but all of my playing with it has yielded no good results for what I'm trying to do
2) with respect to #1 (trying relative view), I could not get it centered properly (tried using param.leftMargin and param.topMargin with varying values but could not get it to work on different devices with different resolutions
3) also with respect to #1, I couldn't make this float over everything else on my screen (need something like a z-index or the like).
any ideas, code examples would be wonderful.
TIA
Use a custom dialog, i.e. a LinearLayout with android:theme="#android:style/Theme.Dialog" and for the class, it would be something like
public class YourCustomDialog extends Dialog implements DialogInterface
where you can implement you custom logic of what to display. Such dialog is floating and modal on top of all other views then and you can also optionally set the background to blurry, etc.
This is a typical constructor of my custom dialog - the layout would be defined in an xml layout file, which in my case is my_custom_dialog.xml:
public MyCustomDialog(Context context) {
super(context, android.R.style.Theme);
Window window = getWindow();
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setGravity(Gravity.BOTTOM);
window.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.empty));
setContentView(R.layout.my_custom_dialog);
// actually not necessary as it's already the default value:
window.setLayout(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
...
}

Categories

Resources