I am working now on app, and I want to do the following:
The user creates a new page (new activity and xml layout).
Saving the user's page to database.
Adding the page to ListView as an item, and launch it when the user
will click it
on the ListView.
I saw many answers here about "Creating Activity Dynamically" and I understand it's
impossible, so i don't know how to do that.
The number of the pages the user can create is unlimited so it must be done dynamically.
Each layout of a page in the ListView is the same.
Thank you very much!!!
Indeed there is no way for dynamically creating new activities.
But you can create multiple instances of the same activity. This will require setting your activity's launchMode to "standard" or "singleTop" .
Additionally, you may use initialization flags to have each of these instances use its own specific layout, creating a user experience which is literally identical as having multiple activities:
Intent intent = new Intent(this, MyDynamicActivity.class);
Bundle b = new Bundle();
b.putInt("LayoutIndex", mode);
intent.putExtras(b);
startActivity(intent);
And the activity:
class MyDynamicActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
int layoutIndex = b.getInt("LayoutIndex");
// and here populate the activity differently based on layoutIndex value
}
}
But how can you dynamically populate different instances of an activity?
Well, there is no easy way. You cannot for example create an ad-hoc XML layout file and store it in
filesystem, because XML layouts must be compiled in a specific format to be loadable by Android.
The only thing you can do is from your Java code dynamically set the layout widgets following the rules
set by the user. Below is an example of how Java layout generation code looks like:
LinearLayout layout = new LinearLayout(this);
layout.setGravity(Gravity.CENTER);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button button = new Button(this);
button.setText("My Button");
layout.addView(button, params);
setContentView(layout);
Have no doubt, creating such a dynamic mechanism will be a lot of work.
Perhaps instead of an Activity you could use Dialog or PopupWindow?
Related
I'm using a predefined Button to add new Buttons dynamically.
But when I restart the application, the dynamically generated Buttons are not present in layout in which they are created.
Code to generate the Buttons.
if(v == btnaddnew) //Button to new buttons in layout Dynamically
{
final Button btn1 = new Button(this);
btn1.setText("New");
btn1.setId(btncount);
LinearLayout ll = (LinearLayout)findViewById(R.id.layout1);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ll.addView(btn1, lp);
btncount++;
}
In main activity
int btncount = 15;
Everytime you close your application and restart it the onCreate method is invoked for your Activity! I suspect you are loading your base layout.xml file, your dynamically added buttons are not part of this layout and are only defined in your code. I am assuming the code to add these dynamic buttons are not in the onCreate, they are probably some button click callback?
My point is this, the dynamically added artifacts will not be present if you close the application for the reason mentioned above!
If you want to resume to the last state after closing it, you need to figure a way to store your current layout before the onDestroy method is invoked for the activity! This stored layout can be reloaded in your onCreate. Let me clear that, in your onCreate you can check if there is a stored layout if yes load from it! Else load from your layout file.
EDIT:
Look at this : http://developer.android.com/guide/components/activities.html#SavingActivityState
I am very new to Android development and I'm trying to figure out the best way to achieve the following goal:
I want to have a main menu that holds several buttons. Each of those buttons should load a second Activity and pass some data to this Activity.
The Secondary Activity should display a tabbar that switches between three different views or activities:
1. A static view created for each element (button on main menu)
2. An image gallery with a set of images associated with that element
3. Another page with dynamic content like a map and images.
My thought: Create a json file for each element and pass the name of that file to the Secondary Activity with could then create the views using that data.
Problem: Can you store the name of a layout.xml file as a string and then load it?
So what would be the best Practice to approach this?
Pass the information of which layout/which views you want to display in the second activity as an extra on the intent used to start the activity:
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
i.putExtra("layout_identifier", 5);
startActivity(i);
Then extract this information in the receiving activity onCreate():
Bundle b = getIntent().getExtras();
int layout = b.getInt("layout_identifier", 0);
switch (layout) {
case 5:
setContentView(R.layout.activity_second_layout5);
break;
Note that the datatype passed does not necessarily have to be int, you can pass all primitives, strings and a third option called Parcelable (https://developer.android.com/reference/android/os/Parcelable.html) which can be thought of as a container for objects.
So I found this
great example of the implementation of Swipey tabs (the tabs UI like in the Android Market).
Is it possible to set an activity as its content? Is there anything like an "Activity Container" that I can set up in the XML and put an activity in it? So basically I want to have multiple activities set as content in the ViewPager. Let me know if anyone has some good solution on this problem.
From what I understand, what you are looking for are fragments, but they are only available for Android SDK 3.0 and above.
EDIT: I was under the impression that an Activity could not be placed inside a View. Apparently I was wrong. Here is an old thread about using a LocalActivityManager to place an activity inside a container view.
In case the thread disappears, the most useful post contains this code fragment:
void createInnerActivity(ViewGroup container, Class<?> activityClass)
{
if (container.getChildCount() != 0) {
container.removeViewAt(0);
}
final Intent intent = new Intent(this, activityClass);
final Window window =
getLocalActivityManager().startActivity(activityClass.toString(),
intent);
container.addView(
window.getDecorView(),
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
}
I have an application that gets information from a database and it creates ImageButtons dynamically. What I want is, when I click a dynamically created ImageButton, I want it to make a search in my database (which I know how to do) and then create a new activity (or screen) with new ImageButtons created dynamically, too.
How can I do this?
You cannot create activities without declaring them in the manifest file. You can either call setContentView after creating the new layout(I do not recomend this.).
Or use the viewflipper and add the the different layouts as childs to it. So you can use the viewflipper to switch between layouts.
Best option is to read the android developer documentation on how Intents can be used to launch a New Activity
An Intent object is passed to Context.startActivity() or
Activity.startActivityForResult() to launch an activity or
get an existing activity to do something new.
(It can also be passed to Activity.setResult() to return
information to the activity that called startActivityForResult().)
ImageButton imagebutton=new ImageButton(this);
imagebutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
getDataFromDataBase();//In this method you get data from database
Intent intent=new Intent(currentactivity.this,newactivity.class);//start new screen.. in this you can create imagebutton dynamically
startActivity(intent);
finish();
}
});
just execute the code that you have inside your onCreate (wrap it in an init(Params param) method), and call that inside your onClickListener. of course exclude the setContentView and findViewById's.
I have a log in page that pulls information from a data base, I then want to use this some of this information to populate different textviews on a new page/activity. I can get a textview to change on the activity where I have my submit button, but when I try to change the textview on my second activity, it just crashed (The application has stopped unexpectedly).
Here's my code for changing the textview (where txtID is my textview on a separate activity)
TextView test2 = (TextView) findViewById(R.id.txtID);
test2.setText(test);
my xml for seperate activity
<TextView android:text="TextView" android:id="#+id/txtID"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
Oh, I'm using a tableview for my login page, then tabs for my the rest of my pages. I'm pretty new to this, so sorry if this is something simple, but any help would be greatly appreciated!! :-)
You don't want to directly touch the UI elements of another Activity. You can make use of bundles to pass information back and forth. Here is an example:
Say we have Activity A, and it has some information as a String it wants to pass to become the text of a TextView in Activity B.
//Setup our test data
String test = "Some text";
//Setup the bundle that will be passed
Bundle b = new Bundle();
b.putString("Some Key", test);
//Setup the Intent that will start the next Activity
Intent nextActivity = new Intent(this, ActivityB.class);
//Assumes this references this instance of Activity A
nextActivity.putExtras(b);
this.startActivity(nextActivity);
So now in the onCreate method for Activity B, we can get that String and assign it as the text to the TextView like you have
public void onCreate(Bundled savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); //Setup some layout, set to your own
String test = getIntent().getExtras().getString("Some Key");
TextView test2 = (TextView) findViewById(R.id.txtID);
test2.setText(test);
}
I'd probably let each separate Activity take care of its own display, and not try to have Activity 1 directly update the display of Activity 2, which is kind of what it looks like you were doing.
The Notepad Tutorial demonstrates an application with two Activities, where one Activity calls another, passing in data. (Take a look at onListItemClick in Notepadv3.) You could maybe follow this model to pass data from Activity 1 to Activity 2, where Activity 2 then takes care of its proper display, using the data it received.
If you're still having problems (like your application crashing), then please post the complete minimal code necessary to replicate your problem. Note the Notepad Tutorial and the Hello, World Tutorial include steps for debugging, which might help you isolate the exact problem.
Andy... If you try to directly touch a UI widget in another activity, your app will crash. Been there, done that accidentally. Instead, consider passing an immutable stateful object between the activities. This can be done using startActivityForResult for instance. I have some sample code here.