Let me preface my question by saying I have done a lot of research in creating dynamic buttons within an android app, and most are simply wrong or have a different view of dynamic than I do. If I missed something then just post the link and I'll check it out.
What I'm looking for is a way to create a button within my app based on information I gather from internet sources. For instance, when someone creates a post on a forums that I care to see, the app will find this, parse it for me, and return some info. Since I can't fit all this info on screen for each post that shows up, I want to create a button dynamically that previews this info. Such as name of user, date, and short description (as a preview that by clicking, will give all of the inforamtion in a separate activity). For the sake of this post, lets pretend I get this info from a text-entry location (not from an actual internt forum post).
First and foremost, how do I create the button dynamically? The other half of my question is less important to me. I would like to do this programmatically. Links to tutorials are great.
Secondly, and less important... Once I have created this button dynamically, how can I get custom views of the button based on a predictable format.
If anything is unclear, just ask and I'll try to clarify. Thanks for all your help!
In my opinion the right approach is to have an Adapter that will map the data to a certain view (a button in your case).
What adapter you choose will be depending on how you decide to fetch and store the data from internet.
When there are new posts you will be adding them to the data source (a database, a list, etc...) and you will call notifyDataSetChanged which will refresh the list, dynamically creating as many views as needed to display all the data.
I think this answers your question. The idea is to programatically create a button, and then add it to the current layout. Somethiug like this:
Button newButton = new Button(this);
newButton.setText("Click Me");
newButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
}
});
container.addView(newButton);
Where container is the layout that will hold the button (i.e. will become it's parent). You can also add layout settings to the button if desired.
Well, you can create a new Button, and set an onClickListener as so:
Button button = new Button(context);
button.setText("New Button");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
If you have anything else you need to set, such as an ID, you can call the method as you wish. You will need then add it to your layout as so:
LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
button.setLayoutParams(params);
layout.addView(button);
There is of course more you can do with it, but that should get you started, and anything else you need you should be able to find by perusing the docs.
If you need help with anything more specifically, then just comment and I will attempt to elaborate.
Related
Firstly, my apologies if this answer is already on here, as I've been searching for a few weeks and haven't found anything yet.
I am working on an Android app which needs to allow the user to create and remove buttons. I know how to normally create buttons statically through adding the button the XML file and creating it's functionality in the JAVA file.
Instead, I have a static button which I'll refer to as "Create Button". When the user presses on the Create Button, they should be given the option to add a new button to the current activity, allowing them to change the title of said button etc. When they close the app and open it back up; the button they added should still be there. Similarly, they should be given an option to remove buttons.
Can someone point me in the right direction? Most of the sources that I've come across only explain how to statically create buttons, like I first mentioned.
Thanks for the help!
EDIT: I was able to figure some stuff out based off of the feedback I've been given.
So far I have the following code in the onOptionsItemSelected( ) method:
if (id == R.id.add_button)
{
Button myButton = new Button(this);
myButton.setText("Push Me");
//myButton.setVisibility(View.VISIBLE);
return true;
}
I am still a little confused about how this can get added to the layout. Mainly, I am confused about the findViewById call:
RelativeLayout layout = (RelativeLayout)findViewById(R.id.?);
Which id should I be using? In the app's main XML file, there is no ID for the layout itself. It's just a "RelativeLayout".
EDIT2:
Actually, I solved the problem. Thanks for the advice! I just needed to give my layout an ID in the XML file. I knew that I could give buttons etc an ID, but never knew that I was able to do so for the actual layout itself!
Creating a button -
Button myButton = new Button(this);
Adding text to it -
myButton.setText("Push Me");
To make the button visible, you need to add it to a view like this. You can also add it to a statically created view -
LinearLayout ll = (LinearLayout)findViewById(R.id.buttonlayout);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
Removing button -
ll.removeView(myButton);
For additional customizations, check documentation.
If you are creating multiple buttons, then I recommend setting id. This example makes it clear.
For making buttons visible after closing the app, you need to store the data on memory. The simplest way to do this is to maintain a record of the buttons and their specifications and storing them before closing the app. After opening the app, you can read the stored data and create the buttons accordingly.
For more details, check Data Storing.
ViewGroup mViewGroup = (ViewGroup) findViewById(R.id.main_layout_id);
mViewGroup.addView(yourButton, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
I'm currently making a local news app and the main layout has 10 image buttons (more to be added in the future) and I was wondering what would be the best way to get each of these to open a separate layout with an individual text view without making 10 seperate classes and maybe even without making 10 separate layouts. Right now my MainActivty class handles the first button from the layout main_activity which opens a new layout named issue.XML.
Thanks in advanced.
You can create a layout called "newsLayout" that has just one text view and sets it from intent and make the onClick listener of the buttons to start a new activity and passing the desired text (the news) to the intent
Here is some code to help:
newsLayout.java
TextView text = findViewById(R.id.text);
text.setText(getIntent().getCharArrayExtra("TEXT"));
mainLayout.java
public void openNews(View view)
{
Intent intent = new Intent(this, newsLayout.class);
intent.putExtra("TEXT", newsText);
startActivity(intent);
}
Where 'newsText' is the text you want to be shown
I may have wrote some lines wrong because im answering from mobile and i dont remember the exact words, if there's anything you dont understand tell me :)
At the moment I am working on a project for a graphical user interface on an Android tablet. On one screen I have several buttons, which I want to make a RelativeLayout visible/invisible with.
I tried using an onClickListener, but in the inner method onClick doesn't support non final variables, which I use to select each button and RelativeLayout.
The GUI is built dynamically, as its whole structure depends on the data it gets fed via an XML file. Also the RelativeLayout uses TextViews which receive an update of their textes (sensordata like temperature and humidity), which is why a dynamic approach is used.
Could you give me some ideas for a workaround around that problem? Help is appreciated. If the stated information is not enough for you, just ask and I will give you more details.
At the moment I tried this:
private void setSensorPointOnClick(final ObjectView currentObjectView, final String currentLinkName)
{
for(int i=0; i<listofSensorDeviceButtons.size(); i++ )
{
listofSensorDeviceButtons.get(i).setOnClickListener(
new View.OnClickListener()
{
public void onClick(View v)
{
arrayClickedButton[i] = listofSensorDeviceButtons.get(i);
mainFrameLayout.removeAllViews();
stepToObject(currentObjectView, currentObjectView.getName());
}
}
);
}
}
either use fields which hold the views that you want to hide/show (and use them in the onClickListener) , or use findViewById within the event handling .
another alternative would be to create another view variable which is final , that will be set just before setting the onClickListener , to hold the reference of the newly created view .
so , in short , the possible solutions i wrote are:
use fields .
use findViewById
use an additional final variable .
Basically what I want to do in my Android app is use TextView to display two different pieces of text at once. So in code, I want to be able to do something like this:
LinearLayout ll = new LinearLayout(this);
TextView text = new TextView(this);
text.setTextColor(0xFF000000);
text.setGravity(Gravity.CENTER_HORIZONTAL);
text.setTextSize(20f);
text.setText("Text1");
text.setTextSize(14f);
text.setColor(0xFF0000FF);
text.setText("\nText2");
ll.addView(text);
To clarify, I am trying to display a black "Text1" and a blue "Text2" at once using only a single TextView. Obviously this doesn't work out using the code above. I've considered using a second TextView but that seems like a waste of effort and memory to me. I'm sure the brilliant minds here can come up with the best solution to this.
Thank you very much in advance for your time and your assistance.
There are two options for you.
One is
Spannable
and other is
fromHtml (String source)
So that you can get your desired output.
I think with the current version of the code, you can see only the latest text (Text2).
If you want to have multiple look and feel for two texts, I would suggest use 2 separate TextViews. It would add more flexibility.
If you are not going to change this UI code later, then you can consider Html.toHtml() in setText() call.
It seems the problem is with:
LinearLayout.addView(text);
You are trying to add a view to a LinearLayout, but the layout doesn't exist (in the current activity). You need to add the TextView to a Layout defined in the .xml you are using. Suppose you have a LinearLayout with id "linearlayout01" in the xml file "activity1.xml", you would do something like:
setContentView(R.layout.activity1);
// Create and adjust TextView text
...
LinearLayout layout = (LinearLayout) findViewById(R.id.linearlayout01);
layout.addView(text);
Once a View is added to a ViewGroup of which LinearLayout is a descendant you do not need to readd it to update its display. If you preform any changes on a view that requires it to change its display it will handle all the proper notifications about required redraws or relayouts by calling View#invalidate and View#requestLayout where appropriate.
In addition, because all UI changes are handled on the same thread you do not need to worry about calling multiple methods that will update the UI. This is because of two reasons, first, the execution of the redraws will not occur until your code is finished, second, android has optimizations built in that combines multiple invalidate calls into one.
So, the only thing you need to worry about is getting a proper reference to your TextView instance and then you can call all the methods on it that you need to make it display what you wish.
Since you are creating your Views manually and not from xml you need to add your root ViewGroup to the Activity by calling Activity#setContentView.
Edit:
Then you're going to need to learn about SpannableString and SpannableStringBuilder. There is some very brief documentation here: Selecting, Highlighting, or Styling Portions of Text
when do you plan to update the textview ? If it is on click of a button then get a reference to the textview and in the onClickListener() update the text, color, etc whatever you want to do.
After seeing your other comments, I think SpannableString is what you are looking for
I am writing an Android app, part of which will be a survey involving multiple pages of checkbox question and answers. I have created an activity to display the question and options (from the DB) and what I want to do now is when i press the "Next" button it should just reload the current activity with the next question set from the database.
(the activity starts with survey.getNextQuestion() - so its just a case of refreshing the activity so it updates)
Im sure this is a simple thing to do -any ideas?
Thanks
Typically you would start a new instance of the activity for the new question. That way if the user hits back, it has the logical behavior of taking them back a page.
It is possible to update the same activity, but it is more complicated.
To open a new activity:
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("nextQuestion", x);
startActivity(intent);
Then in your onCreate method, you can pull the next question from the database.
Im sure this is a simple thing to do -any ideas?
It is pretty straight forward, yes. Mayra's answer is perhaps the better one, however here is an approach that will achieve the functionality you specified.
You can use findViewByID(int) to identify the View objects in your layout that need to be updated, and assign the result to an attribute in your onCreate to allow you to access it later.
E.g.
aView = (View) findViewById(R.id.aview);
Your survey.getNextQuestion() can obviously be used to get the next question.
The question can then be placed into the UI by manipulating the Views you obtained in onCreate.
E.g.
aView.setText("your question/answer");
Depending on the number of answers you may need to programatically create/remove checkbox Views from your layout
E.g.
ViewGroup yourViewGroup = findViewById(R.id.yourviewgroup);
View yourView = new View();
//Configure yourView how you want
yourViewGroup.addView(yourView);
youViewGroup.removeView(yourView);
All of this functionality can be contained in a function that is called by the onCreate method and when the next button is pressed.
Don't forget to store the result of the previous question before refreshing ;)