ViewBinding. Missing required view with ID in dialog fragment - android

I have a problem adding TextView to a dialog fragment. The task looks simple, I have the following UI in my application.
Then I got the task to add just a TextView so that if I click on Weeks this textview changed its visibility from Gone to Visible. The xml for TextView looks like this.
<TextView
android:id="#+id/tv_weekdays_some_selection"
style="#style/TextAppearanceDescription"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="On Monday"
android:gravity="center_vertical"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/time_format_custom_repeat" />
But when I start the app I get the following Exception:
java.lang.NullPointerException: Missing required view with ID: debug:id/tv_weekdays_some_selection
The thing is that I don't even use it anywhere.
Viewbinding sees this View, but for some reason it doen't want to show it in the dialog.
I have tried to remove extra attributes from TextView, tried to clean cache and restart but it didn't help.
Do you have an idea why it's happening?

Related

How do I make a certain component have a relative layout with another component outside of its linear layout

So, the title may be confusing, but to put it in context:
I have an ImageButton component in my app display that should be on the opposite side of my ImageView, lined up perfectly, and to repeat this for any other item on the same list.
My question and doubt itself is how to do this when the ImageButton in this case is inside a LinearLayout while the ImageView is outside of it. Is there like a code line that can connect an outside element to a LinearLayout inside element.
Here's how my display looks:
item_contact.xml
The blue rectangle, being the LinearLayout, means everything inside belongs to it, but the call button looks to be the on the other side of the user pic, which is not inside the LinearLayout, which is what I wanted, the problem is this:
activity_main.xml
Each of the TextViews are above and below both the user picture and the call button, but because they both also belong to the LinearLayout, it's obvious it's because of the latter.
Now I tried fixing the problem by simply adding the user picture to the LinearLayout, which seems like the obvious answer, but I needed to be sure, because my call button isn't correctly aligned to the right:
<ImageView
android:id="#+id/iv_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="16dp"
android:contentDescription="#string/todo"
android:src="#drawable/ic_baseline_person_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="ImageContrastCheck" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="#id/iv_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<TextView
android:id="#+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:textColor="#color/purple_700"
android:textSize="18sp"
android:textStyle="bold" />
<ImageButton
android:id="#+id/call_button"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginStart="248dp"
android:background="#1072E1"
android:contentDescription="#string/call"
android:minWidth="48dp"
android:src="#android:drawable/stat_sys_phone_call" />
<TextView
android:id="#+id/tv_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textSize="14sp" />
</LinearLayout>
My ImageButton's "right alignment" was only done with the manual positioning of the android:layout_marginStart which I set to 248dp by attempts. Surely there's a better way to do this, but I've yet to find a solution that works.
Lastly, there's also the aforementioned problem: I can't seem to fix the LinearLayout issue without having to backtrack the progress I've done and use new code lines or already existing ones to resolve the issue.
So:
How can I "connect" two components, one inside a LinearLayout and another not, with or without the use of constraints and/or RelativeLayouts, and do I really have to insert the outside component to the LinearLayout;
How can I forcefully align a component to the right without having to manually push it with margin inputs (attempts);
Is there a way to know exactly how to connect a component to another by using constraints accurately, so it repeats that process through the entire contact list?.
I would really like if someone could answer at least one of the listed questions or, even better, resolve one of the most developed questions, where I show some images of reference.
Maybe even a suited tutorial for my case in specific that explains the ways of designing the layout of an app.
If more information is needed, I will gladly help, and I'll also try to answer to every response I can get.
Also, in case you're curious, here's my last question about the same app (already resolved):
"[AppName] stopped working" when I try to run my app on an AVD emulator
(Keep in mind that the problem at hand in this question has barely anything to do with this one.)

TextInputLayout, setError increases height

I have a simple TextInputLayout:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/tilPwd"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Passcode"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" >
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
Then I have other views below.
The issue is that when I set the error on the TextInputLayout the height increases and pushes all the views below.
I tried a workaround setting a blank helperText, but when in talkback the blank helperText will be read and that's not what I want.
Is there a clean solution other then wrapping the TextInputLayout in some ViewGroup with a set height?
After a day of tries, I actually found the solution:
public void setHelperTextEnabled (boolean enabled)
Whether the helper text functionality is enabled or not in this layout. Enabling this
functionality before setting a helper message via
setHelperText(CharSequence) will mean that this layout will not change
size when a helper message is displayed.
Basically it occupies in advance the space of the helperText (even if it's not set), and that's the same space occupied from the error.
Worth to notice that the equivalent xml attribute "app:helperTextEnabled" does not solve the issue.
Yes, When you enable the error attribute of TextInputLayout, it will always increase the height of the View to show the error(whenever occurred), which will cause other Views/ViewGroups to push further below.
What you can do to get rid of the extra space is set the error programmatically.
For example, whenever an error occurred(or whenever if you want to set the error) you can call
setErrorEnabled(boolean value)
so that it can also show the error and will push other views down (which are below it), and if the error is gone(or you want to hide error), then you can call
setError("")
where you need to pass an empty string and then call the setErrorEnabled(false), so the textInputLayout will come back to its original position.
I had the same problem and solved it by adding this XML attribute.
app:errorEnabled="true"

Constraint Layout - Group visibility is not working inside dynamic module

Has anyone experienced issues with ConstraintLayout group visibility?
I'm using ConstraintLayout 1.1.3 and I'm setting the visibility of group in both XML layout and java code. But it does not change the visibility status. It is always visible.
This is the layout file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_message_icon_activity_dictionary"
android:layout_width="#dimen/message_icon_width"
android:layout_height="#dimen/message_icon_height"
android:layout_marginBottom="#dimen/message_text_view_margin_top"
android:contentDescription="#string/app_name"
android:src="#drawable/icon_error"
app:layout_constraintBottom_toTopOf="#+id/tv_message_activity_dictionary"
app:layout_constraintEnd_toEndOf="#id/tv_message_activity_dictionary"
app:layout_constraintStart_toStartOf="#id/tv_message_activity_dictionary" />
<TextView
android:id="#+id/tv_message_activity_dictionary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginStart="20dp"
android:gravity="center"
android:textColor="#color/black"
android:textSize="#dimen/medium_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="#string/msg_no_internet" />
<Button
android:id="#+id/btn_try_again_activity_dictionary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/try_again_button_margin_top"
android:background="#drawable/rounded_button"
android:minHeight="30dp"
android:minWidth="#dimen/try_again_button_width"
android:padding="10dp"
android:text="#string/btn_try_again"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="#dimen/text_size_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_message_activity_dictionary" />
<android.support.constraint.Group
android:id="#+id/group_component_activity_dictionary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="btn_try_again_activity_dictionary,tv_message_activity_dictionary,iv_message_icon_activity_dictionary" />
</android.support.constraint.ConstraintLayout>
What could be the reason for this?
UPDATE:
I forgot to mention that I'm using this layout inside of a dynamic module. Also I tested this using in the base module and it is working as expected, but not in a dynamic module. So finally I figured out the reason for the issue. Also when I debugged the code and evaluated this expression (group.getVisibility == View.GONE), it gave me TRUE.(even though the views inside the group are still visible)
Any suggestion is appreciated.
Found a fix for this issue and I hope this will save time for someone else. It's strange but the reason for this issue is using the ConstraintLayout - Group, inside a dynamic module.
So the fix is in java code, once you got a reference to the group then set the reference ids using int array like below,
Group group = findViewById(R.id.group);
group.setReferencedIds(new int[]{R.id.btn_try_again_activity_dictionary, R.id.tv_message_activity_dictionary, R.id.iv_message_icon_activity_dictionary});
After this, it works as expected. Therefore no need to set visibility of individual views in the group.
Don't forget that you can use androidx.constraintlayout.widget.Group only if the parent view is constraintlayout if the parent is LinearLayout then it will not work, then you can try this answer
which says that you add your required views inside FrameLayout or LinearLayout then set the visiblity of the sub parent view.
I was having the same issue using ConstraintLayout v1.1.3. I was setting the visibility of the group in the XML but it wasn't working.
As ConstraintLayout v2.0.0 is already on beta, I migrated from v1.1.3 to v2.0.0-beta2 (check the latest version) and the issue is not happening anymore. I can now change the visibility of the group from XML or code without any problem.
I have the same problem even though I'm on 2.0.0-beta8.
group.visibility = View.GONE/VISIBLE doesn't work but group.isGone = true/false works
This will be fixed with ConstraintLayout 2.0.2.
https://androidstudio.googleblog.com/2020/10/constraintlayout-202.html
I have to add what was my problem - I mistakenly did not put the Group widget inside a ConstraintLayout and could not figure out how come it's working in one layout and not working in another.
Thankfully, I didn't spend that much time on it but this mistake still can happen.

Adding clickable views dynamically to ScrollView

I'm a newbie to Android development, so apologies if the answers seem obvious to others...
I want to create a task tracker app for my org, where the set of tasks are usually about the same. Here's a mockup:
Project Progress Mockup
The mockup shows generic task names, but the real one will have different task names and more of them.
I need some help sorting out the layout design. Conceptually, this is pretty straightforward, but the implementation in Android turns out not to be so straightforward...
I thought I should create a "Task Item" class which contains 3 views: a text view for the task name, a progress bar & another text view for the percentage. Then I wanted to create an array of these Task Items.
Setting all this up in XML is not so bad, but I need it to be dynamic, as it will not always be the same list. Also, using XML is kinda brute force, as I would need to have unique code for each item in this activity, rather than looping through the list dynamically.
It seems like I need a ScrollView. I saw from another post the following statement:
A ScrollView is a FrameLayout, meaning you should place one child in it containing the entire contents to scroll; this child may itself be a layout manager with a complex hierarchy of objects. A child that is often used is a LinearLayout in a vertical orientation, presenting a vertical array of top-level items that the user can scroll through.
So I understand that I need to add my list of Task Items to something like a LinearLayout, which is embedded in the ScrollView. This I can simply set up in XML, right?
Then, for each Task Item, I need to:
- create 2 TextViews
- set the text to the task name & percentage, respectively
- set the font, font size, text color, etc.
- set the TextView positions
- create a Progress Bar
- set the Progress Bar position & percentage
None of this is trivial. So I wonder if it would be easier to set up an XML layout for a single task item & then somehow load() the XML layout. Hopefully from there I could simply set the text & Progress Bar percentage. Would this work, or am I going about this wrong? Also, how would I set up the XML for this? Do I add an activity to my project, or just another XML file?
Finally, I need the task name to be clickable, so I can capture the click & open a new activity showing the subtasks for a task & allowing the user to change the status. Therefore the task name TextView needs to have an ID. Should I make the task names Buttons rather than TextViews? How can I set the ID dynamically? I see that there is a setId(int id) method for Views. But how do I know what integer to use? Android reference View.html states:
View IDs need not be unique throughout the tree, but it is good
practice to ensure that they are at least unique within the part of
the tree you are searching.
How do I ensure that these IDs are unique?
In the XML file, IDs are not numbers, but rather text, like:
android:id="#+id/my_button"
And this is referenced in the code like this:
Button myButton = findViewById(R.id.my_button);
But how do I create & use unique numeric IDs in order to capture click events on these task names?
Thanks for any pointers you can give!
New information & questions...
I have the basic functionality working, but a couple things aren't quite right:
If you look at my updated mockup, Updated Project Progress Mockup, I want the area highlighted in green to scroll, while the rest stays in place. However, the heading at the top & the button at the bottom scroll off the screen and won't come back. Not sure what I did wrong.
My layout xml looks like this:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/summary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBG"
tools:ignore="LabelFor"
tools:context="com.myorg.myapp.ProjSummary">
<TextView
android:id="#+id/txtSumm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/summ"
android:textAppearance="#style/TextAppearance.AppCompat"
android:textColor="#color/colorPrimaryDark"
android:textSize="18sp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/txtProj"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="#+id/txtProj"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/proj"
android:textAppearance="#style/TextAppearance.AppCompat"
android:textColor="#color/colorPrimaryDark"
app:layout_constraintTop_toBottomOf="#+id/txtSumm"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/edtProj"/>
<EditText
android:id="#+id/edtProj"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:paddingTop="5dp"
android:paddingBottom="0dp"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:textColor="#color/colorPrimaryDark"
android:textSize="14sp"
app:layout_constraintTop_toBottomOf="#+id/txtSumm"
app:layout_constraintLeft_toRightOf="#+id/txtProj"
app:layout_constraintRight_toRightOf="parent"/>
<ImageView
android:id="#+id/imgLogo"
android:layout_width="120dp"
android:layout_height="48dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/btnSend"
app:srcCompat="#mipmap/my_logo"
android:contentDescription="#string/org_logo"/>
<Button
android:id="#+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/colorSecondaryDark"
android:text="#string/send"
android:textColor="#color/colorButtonText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/imgLogo"
app:layout_constraintRight_toRightOf="parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rvTaskList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/txtProj"
app:layout_constraintBottom_toTopOf="#+id/imgLogo"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
My last task item never is displayed. (i.e. if I have 10 task items, only the first 9 are displayed.) In my activity class, I have an ArrayList for the summary list of task items:
private ArrayList _alSummaries;
And in my RecyclerView.Adapter class, I have the following method:
#Override
public int getItemCount() { return _alSummaries.size(); }
Anywhere else I should look?
Thanks!
Further update:
in my layout I had...
android:layout_height="wrap_content"
Rather than wrap_content, it should have been "0dp". Seems like a bug in Android, actually - if I say wrap_content, that should never cause the view to become larger than the space available to it (as set by the constraints).
Problem solved - not a problem with the interface, but with the code that loaded my data into the app.
So I wonder if it would be easier to set up an XML layout for a single task item & then somehow load() the XML layout. Hopefully from there I could simply set the text & Progress Bar percentage.
This is what a Recycler View adapter does. You have an xml layout containing the three simple views: a text, the bar and another text.
Now in your code (in the adapter), you inflate each row and set the text and progress bar individually.
Should I make the task names Buttons rather than TextViews? How can I set the ID dynamically?
You do not need to do that. You can just assign custom onClick listeners which do what you want in the adapter code.
For a beginner, the setup is definitely not trivial, but once you get the hang of it, you will find it to be a very valuable tool.
Look here for the official tutorial: https://developer.android.com/training/material/lists-cards.html

Android Databinding onClick() not getting registered on a simple View

I am trying to call a method from my ViewModel through data binding, but the method isn't called. This is how the view looks:
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:alpha="0.8"
android:background="#color/black"
android:onClick="#{()->viewmodel.onViewClicked())}"
/>
If I change the view to a button instead, without modifying anything else, it works as it is, so I think this may be a weird interraction between simple View and databinding. I also tried adding clickable:"true", it still doesn't work.
Do you guys have any idea why this may happen ?

Categories

Resources