I have one of those screens where you fill user info, some other EditTexts etc. and send it to server. But there is section something like add note (just example). User can add as many notes as he want. At the beginning there is just button add note. When user press it then new TextView spawns above and he can fill it, or remove it. Then he can touch add note again and whole process repeats. You sure know what I mean. At the end I take all filed notes and send it to server.
I know that the way to do it is - on btn press inflate my TextView + delete btn layout and add it to linear layout. On btnPress then get its parent or whatever and remove it from layout.
However this is pretty annoying thing to do as it requires inflating, children views managing and all the other stuff. What I am asking is - is there some other way to do that? Maybe some library, or possibility to set adapter to linear layout etc.
Thanks :)
Related
I have looked everywhere but don't seem to be able to find what I am looking for. I have an activity with multiple buttons, each button opens a new activity with an identical recyclerview layout, but different data. I am wondering if it is possible to use one activity and layout instead of multiple? this way instead of having 10+ activities (one for each button) I only have to manage one when a button is clicked and simply pass the necessary list data to it.
I believe you could set the intents for each button to call the same activity but with an integer such as 1-10, in the activity it takes the value and decides which list should be presented? If anyone thinks of how this could be done or a simpler way I would greatly appreciate it!
Yes, there are various ways to do that.
You could use multiple fragments on the same activity. Then add/remove fragments on each button click.
You can have multiple layouts within your activity. Say you have two buttons, and you have three layouts layout1, layout2, layout3, sequentially one after the another. So if initially, layout1 is visible and the rest are gone using layout.setVisiblity(View.GONE), if you click button1, ypu can do layout1.setVisiblity(View.GONE); layout3.setVisiblity(View.GONE); layout2.setVisiblity(View.VISIBLE) and vice-versa for pressing button2.
Are all the activities opened by the buttons similar? If so, you could only take care of the changes in the elements of the layout & specify conditions.
For instance, if you click a button, instead of changing the whole thing, you only go into the buttons & change their texts with btn.setText("..."). You could define different conditional statements inside the onClickListener of that button.
It could be something like:
if(btn.getText().equals("a certain text that you set to the button")){
doSomething();
else if(btn.getText().equals("another option")){
doSomethingElse();
Following this logic, you could continually update the elements in your layout & your code will decide what to do depending on what's stored in these elements.
The second option that comes to my mind would be creating different xml layout files & simply changing the layout of your MainActivity to the appropriate one depending on what stage of your process you are at.
I hope this helps,
I have a layout which takes user's children information. Let's say that this layout takes info about the children's first name, last name, and age. I am taking inputs with EditText. And there is a spinner which shows children Allergy type, on selecting 1 Allergy type it has to fetch its details from webservice and to fill those details in a textview.
So in this way the User can add as many children as he wants. The problem occurs there. Let's say the user has added that layout 4 times now, he selects the spinner of children 1 and service gets called and it fetches the information and fills it in the last layout textview that was added.
where as it is expected the details should fill in each textview of each layout added accordingly.
Confusions :
How can I exactly get which view is clicked and then how to take action in the same layout of that view not the one which is added recently?
I am inflating layout which has the specific set of fields specified above. So I am maintaining the Array List of each layout added , so Is there a work around to get exactly the same view and its corresponding view in that layout ??
UPDATE 1: Some Idea of my question
There is a main activity it has 1 button named "Add More Children". When user click on this the layout which contains the children info adds in the specified area in the ScrollView, so that user can add as many children as much he want.
so basically I have drawn some views below where as there are too many views in the following layout named children layout.But this layout shows what type of work is need to be done . so see below and have some idea
For demonstration you can see there are different edit text and spinners. Spinners get updated from Webs service and each children may have different data loaded in spinner from webservice. this whole layout inflates into the mainactivity. on button click named Add Children . so on that button I am adding this in the scrollview
private View addChildLayout(int childLayoutid, LinearLayout Targetlayout) {
//where childLayoutid is a layout resourse id of childern layout
// where Target layout is a scrollview in my fragment
LayoutInflater inflater = LayoutInflater.from(getActivity());
View inflatedLayout1 = inflater.inflate(childLayoutid, null, false);
inflatedLayout1.setId(numOfChildAdded);// numOfChildAdded is int number of children added by user so far
Targetlayout.addView(inflatedLayout1, 0);
numOfAddedChildLayout.add(inflatedLayout1);//this is an array list i am creating to keep track of each layout added by user on add button click
return inflatedLayout1;
}
after adding this in layout another method I call that finds the ids of this layout and sets the click listener of each views i.e spinners or edit text or whatever is needed. Now suppose User has added one children. and clicks on the spinnerAllergy types that fetches sub category and populate spinnerSubCatogry, and spinnerSubcategory when clicked the web service again gets called and gets details of allergy and fills in the Textview (the large box shown in picture)
Now the main problems comes in when user added Children no 2. now let suppose user has added 2 childs , but he clicks on the spinnerAllergy of Child1 , the child1 spinners runs the web service but populates the spinnerSubcategory of Child2.
It Looks like that when the new child is added the click listener refers to new layout which is newly added .
so that is the main problem . I want each view in each layout work accordingly in its views and boundaries. I mean child1 layout views click listener should populate its views not the currently added layout views.
I think that is enough information to get some clear idea.
Please help me with this, I've been stuck here for 2 days. Where as all my design is working good.
Well as you stated above that you are keeping track (List of ) every single view you have added. I will suggest you to use that
Here are the lines you are using and setting the id so its mean each parent has the different id where as their child views has the same id ,
View inflatedLayout1 = inflater.inflate(childLayoutid, null, false);
inflatedLayout1.setId(numOfChildAdded);
As you are adding each layout with different ID why dont you simple get the parent and then again get the child with the specific id , for demonstration
Suppose there is a textview in you layout , and that under the Linear layout where as that linear layout has a relative layout as a root/main layout , and every main layout has different id as you have done above. so this is how you will go to the top(parent ID)
ViewGroup row = (ViewGroup) yourTextView.getParent().getParent;
TextView textView = (TextView) row.findViewById(R.id.tvClassLevels); // the next view you can find
so here I will suggest to do this with each view and then set click listener.
this may not be more efficient but this would work. I have done that once When I was inflating my custom layout but keep that in mind every time inflating though may be quick but it would be costly , you need to implement some logic near to getview (as we have its implementation in adapter)
Why I am doing getParent().getParent() twice
As I said that my textview is in linearlayout and that linear layout lies in the main/root layout and hence as we want to approach the mainlayout because we know it is the only one which has different Id , so we are doing getParent() twice as Textview has LinearLayout as first Parent and then the root layout comes, so in this way if you have a view in another layout , you need to dig it by yourself.
Again I am saying , it may be not a cool or best implementation , but it works . At least it worked for me.
I think the problem is : Different views in your layout have SAME id since you're inflating from the same xml layout.
You have different approaches to solve this:
Keep track of a variable and increment the count whenever you add a Child View. Once the inflation is done, you call setId on the newly created View(just as mentioned in Abdul Salam Ali's answer). Although view ids in android are generated at compile time(correct me if I'm wrong), this should work perfectly in practice.
Create a Ids resource file in res/values folder and pre-define a few Id values for future use. It's guaranteed that all id values will be distinct. But as you say, users can add as many child info as they want, this may not be the best choice.
Use Random to generate different ids.
Please note that even if you have same Ids in your layout, your code logic would be correct as long as the childs of ViewGroup on which you call findViewById(or sth similar to this) has a unique id. See this
For some suggestion to your design.
Use the listview and adapter design instead of generating the view in programming.
a. Add the new item
Used floating action button. https://material.google.com/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button
B. Remove the item
Used some list control or multi selector to remove the undesired items.https://material.google.com/components/lists-controls.html#lists-controls-types-of-list-controls
Use listview to show your item instead of generating layout in your code.
https://material.google.com/components/lists.html#lists-usage
To edit the specific child information, suggest to use the full screen dialog for editing.
https://material.google.com/components/dialogs.html#dialogs-full-screen-dialogs
The above is my suggestions toward your design, since it would be difficult if you want to get the clicked view's parent to find your actual position in the layout, and then send to to listen the corresponding on click event. It would be hard to maintain and your code will be hard to debug if there is any nested view in your parent. Try to separate each part to help your debug what is wrong in your code.
I have a dynamic UI that I need to generate and I would like to know what the best approach would be to do this and why? The application that I need to make will either way only have a single activity in which to display various different views which are generated by code, so not in an XML file.
So basically I want to draw one set of views and have a user interact with them (textview, button, radio button, edittexts etc). Then save the data he generated, clear the canvas or screen and within the same activity generate the next set of views for the user to interact with.
I have done extensive research and I know that I can use either a Fragment or an Activity with a LinearLayout to achieve this, but I am not sure which would be better and why?
Thanks,
Wihan
I have a problem loading previously created layout. I would like to load it and change text on buttons inside, then show it to the user. It will be quiz question and I have to show it many times during one activity. I don't want to create new class for my layout.
What do I have to use? I read something about Inflate class, but I think it is used only to create new classes. I tried setContentView() method, but app stops when method doing this load starts:
LinearLayout layout = (LinearLayout) findViewById(R.id.CapitalQuestionLayout);
setContentView((View) layout);
Can someone give some hints?
Try using the layout field not the id field, when you call from the R class, like so :
LinearLayout layout = (LinearLayout) findViewById(R.layout.CapitalQuestionLayout);
setContentView((View) layout);
For creating a "Quiz" app your basic requirement is:
a layout which has a TextView for Question and 4 Buttons for options.
a set of questions; pretty obvious :-).
You can create a Custom Class - Questions that will hold Text for a question and its associated options (as Strings).
Now, whenever you want to display a new question with different text for buttons just do the following:
If user clicks on right answer then display a Right-Answer-Activity to the user (that has a next-question-Button).
When user clicks on next-question-button you can display Question-Activity and populate the layout-views with a randomly picked question-object's attributes (i.e. Question's text and options' text).
Hope this helps.
This is quite common in Android apps. Do your fields/buttons have an id? For the parent activity, you mostly do
Button someButton = (Button) findViewById(R.id.the_id_to_the_button_you_want_to_change);
This allows you to do things like
someButton.setText("What is the ultimate answer to life, the universe, and everything?");
Look up the Andorid documentation if you want to do other things like set the color. If you have a viewgroup of some sort (RelativeLayout / LinearLayout / etc), you can specify that specific one
Button someButton = (Button)viewGroup.findViewById(R.id.awesomely_named_button_identifier);
The above someOtherButton is used more often with inflated viewGroups
I want to create a XML layout dynamically but I had a question on doing so.
Say I have something like this (Looking at the layout from the "Outline" perspective):
-ScrollView
---Linear Layout(Vertical) (LL1)
-------Linear Layout(Horizontal) (LL2)
-----------Image View (IV1)
-----------Linear Layout(Vertical) (LL3)
---------------TextView
---------------TextView
So my question here is would I start with the most inner Layout (LL3) and add the 2 TextViews and then branch upwards (to LL2 then LL1 then ScrollView) with adding to the other views & layouts?
I believe you can do this several ways. I've not tried creating an entire hierarchy like this dynamically, but I've added buttons, radio-buttons, text-views and other Views this way several times. In those cases, I've just added new ones to the ones that already exist using AddView().
I think the easiest way is to just create it "top down", i.e. create the ScrollView first and add any settings, then add the other views to it downwards. I would typically do something like this:
// Call other methods to create the views first:
ScrollView myScrollView = createMainScrollView();
LinearLayout myHorizontalLayout = createLinearLayoutForAbc();
LinearLayout myOtherLayout = createLinearLayoutForXyz();
TextView myFirstTxt = (...)
(..etc..)
Now populate them in the right way:
myScrollView.addView(myHorizontalLayout);
myHorizontalLayout.addView(myOtherLayout);
(..etc..)
Note:
I do believe this should work, but I can not guarantee it; if the reference to an inner view is no longer correct after having been added to an outer view (Eg. myHorizontalLayout is no longer a valid ref to the actual view under myScrollView), you might not be able to add children to that inner view. Not sure about this, though.
(If so, you might try to fetch a new, correct reference using findViewByName() after adding each view, but I don't think that would be an optimal solution).
I would try the first way first - at least make a proof of concept, to see that you can add view in a hierarchy at least three levels deep. That should give you your answer. If it does not work, I suppose I would try adding them in the opposite order, as you suggest in your question, just to see if that works (maybe just switch the order in my second code block?).
Sorry for the imprecise answer, hope it is of some help anyway.