When my application starts I want to have a start game button. When the button is pressed I want another activity to be shown.
In XML I Setup the button like this:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"
/>
And this is the Java function:
public void startGame(View v ){
setContentView(R.layout.activity_start_menue);
}
My app crashes when I click the button.
Calling setContentView() multiple times is dangerous, and doesn't always work. There can be hierarchy conflicts, and inefficiencies that result from instantiating views multiple times. It's also not that helpful, because you're not in control of the container that the layout expands into.
Here is the proper way to do it.
Android provides a built-in mechanism for view-switching called a ViewFlipper. Instead of calling setContentView() for the layout you want to swap in, you can tell the ViewFlipper object to either showNext() or setDisplayedChild(int).
Here's how you would accomplish that in your main.xml.
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewflipper"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- The ViewFlipper can change through its direct children -->
<!-- Child 0 -->
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"/>
<!-- Child 1 -->
<LinearLayout
android:id="#+id/activity_start_menu"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here's the menu!"/>
</LinearLayout>
</ViewFlipper>
Note that the views being flipped through are direct children of the <ViewFlipper> that you are using. FYI, you can have more than just two views.
Now onto the Java code in your `MyActivity'.
public class MyActivity extends Activity {
ViewFlipper viewFlipper;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
}
/**
* Switches to the activity_start_menu LinearLayout
* specified in the ViewFlipper.
*/
public void startGame(View v) {
//First way -- use showNext() & showPrevious()
viewFlipper.showNext();
//Second way -- use setDisplayedChild(int) where int is
// the index of the view starting from 0
//In this case, there are two. 0 is the button,
// and 1 is the menu layout.
viewFlipper.setDisplayedChild(1);
//You can also do fancy animations to switch between views.
// Check out the methods accessible and experiment with them!
}
}
You should end up with something like this:
Start activity
Draft:
onCreate()
setContentView(//layout 1);
Button lButton = (Button) findview....
lButton.setOnClickListener(...)
{
onClick()
{
setContentView(//layout 2);
}
}
To start new activity you should use:
Intent intent = new Intent(this, YourActivity.class);
startActivity(intent);
Or if you wouldn't change activity use for eample viewswitcher to switch layout, fragments etc
Related
I would like to know how to add new strings at the bottom of a ScrollView every time I press a button.
For example at the beginning there is sentence1, press button, then sentence2 is under sentence1, press button, sentence3 is under sentence2, etc
I know how to make a scrollView and I have an array of strings to display:
final int[] sentences = new int[]{
R.String.sentence1,
R.String.sentence1,
R.String.sentence2,
R.String.sentence3,
R.String.sentence4
};
And I know how to make them appear one after another when a button is pressed (kind off replacing the previous one, like a TextSwitch but without the animation) :
if(nextSentenceId < sentences.length) {
officeOBSDialog.setText(sentences[nextSentenceId]);
++nextSentenceId;
}
Do you have any idea how I could manage to do that or what could I use? It occured to me that I could use like a layout inflator but I don't know how to put that to practice and where to put it. Thanks in advance
I recommend you to use ListView or RecyclerView.
https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
However, if you consistently want to use ScrollView cause your screen UI is simple. You can simply wrap a LinearLayout with vertical orientation by a ScrollView.
activity.xml
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:id="#+id/lnContainer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- your button declaration -->
</LinearLayout>
</ScrollView>
In your activity java file, add new row programmatically by:
private int position=0;
final int[] sentences = new int[]{
R.String.sentence1,
R.String.sentence1,
R.String.sentence2,
R.String.sentence3,
R.String.sentence4
};
//inside onCreate() method
yourButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
TextView textView = new TextView(YourActivityClass.this);
textView.setText(sentences[position++]);
((LinearLayout)findViewById(R.id.lnContainer)).addView(textView);
}
});
I spent an hour trying to add "Load More" Button and indeterminate ProgressBar to the footer of my ListView.
The supposed scinario works like this:
When the button is clicked, ProgressBar is shown while AsyncTask is downloading 20 items. when the items are inserted to the ListView, the ProgressBar dismisses and the Button appears again in the footer.
I come to the following solution and would be nice if you have better solution:
layout/progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
/>
And assuming you have the following fields in the Activity:
private ListView listview;
private Button loadMoreButton;
private ProgressBar progressBar;
after preparing your list view add the footer like this, (at the end of the activity.onCreate()):
loadMoreButton = new Button(this);
loadMoreButton.setText("Load More");
progressBar = (ProgressBar) LayoutInflater.from(this).inflate(R.layout.progress_bar, null);
loadMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//downloadItems();
listview.removeFooterView(loadMoreButton);
listview.addFooterView(progressBar);
}
});
When the data is ready (either first page or subsequent pages), call the following after adapter update.
//adapter.notifyDataSetChanged();
listview.removeFooterView(progressBar);
listview.addFooterView(loadMoreButton);
If you have better solutions, please share it in the answers.
Instead of removing and adding a view as footer.. you can have both button and progressbar in the same footer view and make visibility VISIBLE and Visibility GONE according to the requirement.
I came to a solution without adding/removing the footer. Just put the two views (Load More Button and ProgressBar) in LinearLayout. Add the linearlayout as listview footer for first time only. Then change between the button and progressbar by changing visibility property.
Here is the updated code:
layout/list_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/load_more_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="Load More"/>
<ProgressBar android:id="#+id/load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminate="true" />
</LinearLayout>
call this method at the end of Activity.onCreate() to add footer and handle button click (load data, hide button and show progress).
private void prepareListFooter() {
View view = (View) LayoutInflater.from(this).inflate(R.layout.list_footer, null);
loadMoreButton = (Button) view.findViewById(R.id.load_more_button);
progressBar = (ProgressBar) view.findViewById(R.id.load_progress);
listview.addFooterView(view);
loadMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//downloadMore();
loadMoreButton.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
});
}
also this code after adapter change to show the button and hide the progress.
adapter.notifyDataSetChanged();
loadMoreButton.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
Ok so in here i have this xml like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_margin="30dp"
android:background="#drawable/backgroundblankred" >
<Button
android:id="#+id/button1"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/eeclevelfirstblackbuton" />
</RelativeLayout>
</RelativeLayout>
it is show like this
the button was inside a layout so i want to make the button when clicked it will be like this
the button randomly move inside the layout there every second and not out from the layout that can make app force close
Second question, how to set the fast of random button move? like set the buton random move every 2 second and increase it more fast, it is possible set the button move faster?
i just have this code now
public class tested extends Activity {
Button buttonblack;
int score=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.tested);
buttonblack = (Button)findViewById(R.id.black1);
buttonblack.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
//If clicked, Move the button randomly
}
});
Anyone can help with some code? Thanks in Advance.
Hope this video helps for the 1st part: Android App Development for Beginners - 34 - Animations and Transitions.
For second part you may use a loop like this:
while(true){
delay(time);//time can be taken input from any EditText.
placeButton(x,y); // x and y are random numbers
}
generate random integers within your view area
random number
1)this should be the pseudo code you are looking for
int x = rnd(view.getX(), view.getX()+view.getWidth());
int y = rnd(view.getY(), view.getY()+view.getHeight());
view.setTranslationX(x);
view.setTranslationY(y);
2) use a thread with a sleep duration you can modify, the ui changes needs be called on the main thread, use a handler or asynctask for that
So far I know how to change the Background's color via html codes. Now I am Trying to change the background of the Layout of my main activity to different images using a button click. If possible using only one single button.
Thank you!
The following code is from this link Setting background image in java from Omi0301.
//assuming your Layout is named linearlayout1:
LinearLayout ll = (LinearLayout) findViewById(R.id.linearlayout1);
ll.setBackgroundResource(R.drawable.sample);
All you do is create a layout variable and set its background resource with the image that you would like it to be.
try to use "setImageResource" instead the "setBackgroundResourse"
Try below code
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="64dp"
android:layout_marginTop="71dp"
android:text="changeColor" />
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
/** Called when the activity is first created. */
Button button;
LinearLayout mainLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout=(LinearLayout)findViewById(R.id.myLayout);
button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
mainLayout.setBackgroundResource(R.drawable.newImage);
}
});
}
}
I am having trouble trying to figure out how to convert my current tab setup to one that uses views and not seperate activities... I have issues with calling my search function and I think it is due to the way I have created my tabs.
My main launcher activity is public class Menu extends TabActivity which creates the tabs
intent = new Intent().setClass(this, TabGroup1.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("codes").setIndicator("All Codes",res.getDrawable(R.drawable.ic_tab_codes))
.setContent(intent);
tabHost.addTab(spec);
`TabGroup1' does the following for each tab
public class TabGroup1 extends TabGroupActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startChildActivity("Category", new Intent(this,Category.class));
}
}
Which then calls the ListActivity which shows the content from there when an item is clicked another intent is created which then starts a new activity which allows me to have the tabs on each level as the user goes down the lists.
This is done with the following code
public void onListItemClick(ListView parent, View view, int position, long id) {
Intent intent = new Intent(getParent(), SubCategory.class);
Cursor cursor = (Cursor) adapter.getItem(position);
intent.putExtra("CATEGORY", cursor.getString(cursor.getColumnIndex("_id")));
/*startActivity(intent);*/
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("SubCategory", intent);
}
TabGroupActivity is a class which I found from a tutorial that allows you to have multiple activities under the same tab layout.
What I am struggling is with converting what I have to using views and using setContent to change the views.
I have found this example but it doesn't provide enough detail for me to go on.
Also found this one as well...
Can someone please provide me the run down on what I need to change and also how do I setContent using my listactivities...
Thanks in advance
A couple things... setContent defines the content, it doesn't cause the switching of tabs. If you want to force a change to a certain tab you use TabHost.setCurrentTab(tabid);, otherwise it defaults to the first tab, then whatever the user chooses.
An example from one of my own projects (This project actually has four tabs, but I've cut out some to try and keep this to the point). There are several ways to do it, but I found the easiest was to create a method to populate each tab, that way I could refresh a tab as needed by calling the appropriate method for whichever tab I needed (all of the java below is contained in the TabActivity).
setupdetailmain.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="#+id/setupheader"
android:layout_width="fill_parent"
android:layout_height="20dp"
android:textSize="15dp" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:gravity="bottom" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" >
<!-- General Info Tab -->
<LinearLayout
android:id="#+id/note_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
<!-- Tool Tab -->
<LinearLayout
android:id="#+id/offset_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#+id/list2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
tab setup code (extends TabActivity)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setupdetailmain);
// ***************************************************************
// Set up the tabs in the tabhost
// ***************************************************************
tabHost = getTabHost();
TabHost.TabSpec spec;
spec = tabHost.newTabSpec("Offsets").setIndicator("Offsets")
.setContent(R.id.offset_tab);
tabHost.addTab(spec);
spec = tabHost.newTabSpec("Notes").setIndicator("Notes")
.setContent(R.id.note_tab);
tabHost.addTab(spec);
populateTabs(StartTab);
}
tab populate methods
// ***************************************************************
// Fill the Notes tab
// ***************************************************************
private void notestab() {
notes = (LinearLayout) findViewById(R.id.note_tab);
notestxt = new TextView(this);
notestxt.setText(SETUPINFO_NOTES);
notestxt.setTextSize(15);
notes.addView(notestxt);
}
// ***************************************************************
// Fill the Offset tab
// ***************************************************************
private void offsettab() {
wpccount = 0;
for (int i = 0; i < 20; i++) {
if (wpcdesc[i] != null) {
wpcdisplayhold[wpccount] = wpcid[i] + " - " + wpcdesc[i];
wpcidhold[wpccount] = wpcid[i];
wpcdeschold[wpccount] = wpcdesc[i];
wpccount++;
}
}
wpcdisplay = new String[wpccount];
for (int i = 0; i < wpccount; i++) {
wpcdisplay[i] = wpcdisplayhold[i];
}
mWPCView = (ListView) findViewById(R.id.list2);
mWPCView.setAdapter(new ColorizingListAdapter(SetupDisplay.this,
wpcdisplay, "Offset"));
registerForContextMenu(mWPCView);
}
This uses a custom adapter, but hopefully it gets across the idea of how to set up your lists in a tab view without doing a new activity.