I am working on a simple android application that has MainActivity with FragmentStatePagerAdapter and some number of fragments side by side. I want to be able to go to the first fragment by pressing home button.
I know my code is pretty bad. Still I hope just a few lines will solve my problem.
Here is my MainActivity
package com.freestylers.druskischool;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity {
ViewPager pager;
FragmentStatePagerAdapter adapter;
* Each page of our pager will display one fragment from this array
* Swiping, to the right will take you to the next page
*/
String[] fragments={
"start",
"mes",
"whatever",
"next",
"name",
"of",
"a",
"fragment",
"more fragments",
"and",
"more",
"fragments"
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pager=(ViewPager)findViewById(R.id.my_pager);
adapter=new FragmentStatePagerAdapter(
//maybe should use normal getFragmentManager()
getSupportFragmentManager()
){
#Override
public int getCount() {
// This makes sure getItem doesn't use a position
// that is out of bounds of our array of fragments
return fragments.length;
}
#Override
public Fragment getItem(int position) {
// Here is where all the magic of the adapter happens
// As you can see, this is really simple.
//(fragments[position]);
if(position==0){
return StartFragment.newInstance();
}
else if(position==1){
return MesFragment.newInstance();
}
else if(position==2){
returnNextFragment.newInstance();
}
//this goes on until position==11
else{return StartFragment.newInstance();}
}
};
//Let the pager know which adapter it is supposed to use
pager.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And this is one of my fragments, MesFragment. On the line 19 (commented out by double slash)I just don`t know which command to use to get to my first fragment:
package com.freestylers.druskischool;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MesFragment extends Fragment {
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case android.R.id.home:
//(getActivity()).getSupportFragmentManager().??? I don`t know how
to go back to first fragment
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
(getActivity()).getActionBar().setDisplayHomeAsUpEnabled(true);
View view=inflater.inflate(
R.layout.fragment_mes,
container,
false);
return view;
}
// This is the method the pager adapter will use
// to create a new fragment
public static Fragment newInstance(){
MesFragment f=new MesFragment();
return f;
}
}
Thanks
You can set the currently selected item using ViewPager, which is in your activity:
public void switchToMesFragment() {
pager.setCurrentItem(1);
}
To switch from within a fragment, you need to get a reference to your activity and call the switching function, like so:
((MainActivity)getActivity()).switchToMesFragment();
You cannot completely control the Home button key since it is a key that is broadcasted to all active apps on the device. If you want to process the Home button for your app, you may overrride the Activity.onPause() method. Documentation # Pausing an Activity. But still you cannot prevent the user from seeing the Home screen, that's not fair to other apps perhaps. Try this out first...
Related
I'm an Android newbie working with the Eclipse IDE and the Android SDK. Anyway, I've watched a few tutorials and I can't seem to be able to call the findViewById() function.
I would appreciate if you could instruct me how to use it, if it's a method of a static class or something else.
Thanks, I'm sure this won't be a problem for the more advanced users!
Well the in response to the comments I'm trying to use it in an Activity.
Here's the code in there:
package tk.quiero.test1;
import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Where exactly am I supposed to use it?
Thanks
findViewById is defined in the Activity class, so it sounds like you're trying to call this from outside of the Activity. If so, you should post what exactly you're trying to do because there are ways of doing this, but there's also a high likelihood that there's a cleaner or easier way than resolving UI elements outside of the Activity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.xxxxx)
}
replace xxxxx with the id that you've defined in your xml...which should look like #+id/xxxxx
I'm trying to create a small game on Android and have some questions on a specific section of my game. I'm fairly new to android so please excuse if I don't have a full understanding of certain things.
When clicking "play" I'd like to view slide-able menu that makes it able for the user to swipe left and right to choose a level. Overtime I will be adding few more levels but have 2-3 of them now.
What would be the best way to do this? Is it best to implement a fragment for each "level page" or create entirely new activities?
My project is compatible for Android ver. 2.3.3 and above, so it's automatically included the "appcompat_v7" project. (I don't know if that makes a difference).
I've pasted my code below if needed:
package com.example.snake;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class SnakeLevelSelectActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_snake_level_select);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.snake_level_select, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_snake_level_select, container, false);
return rootView;
}
}
}
What I intended to do was create several fragment classes and animate between the fragments when the user swipes. I also have issues understanding on how to use several fragments with the "PlaceHolderFragment" class, since the solutions I've found on SO have been different. This is an entirely question, but would be appreciated if it was answered as well.
What would be the best way to do this? Is it best to implement a fragment for each "level page" or create entirely new activities?
This is exactly what a Fragment is for. What you are looking for is already there and named ViewPager. Using ADT and Eclipse you can even create an Activity with this already implemented. Use the "Navigation type" combobox for that purpose:
You can also choose "Action Bar Tabs (with ViewPager)", which will enable Tabs in the ActionBar and make sure that you can switch to different Fragments using both the swipe gesture as well as the tabs.
Android now has this built-in in the SDK.
They call it the Navigation Drawer.
Look up the documentation it contains sample project, it is very easy to implement.
I have created my view how I want it to look. It has 1 images, an input box, and a button. I will want to load another activity when the button is clicked. I am confused why there are fragments and activities. I am new to the Android world (coming from iOS).
My understanding is that Activities are similar to ViewControllers, but I am not sure I understand what a fragment is.
Where do I put the event handling?
package com.phppointofsale.phppointofsale;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
public class StoreUrlActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store_url);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new StoreUrlFragement()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.store_url, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class StoreUrlFragement extends Fragment {
public StoreUrlFragement() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_store_url,
container, false);
return rootView;
}
}
}
Firstly I would recommend reading this Fragments . Pay particular attention to the created fragment section, which includes the fragment life-cycle diagram. Second download and compile this Sample App,the effective navigation app will help you understand how different fragments work in tandem, and even implements a action bar.
To answer your question more or less a fragment can be thought of as a separate class. Once you call upon that particular fragment you can call functions from within that class.
Fragment Case-Switch
This is some sample code to show you what I mean.
public Fragment getItem(int i){
switch (i) {
case 0:
// The first section of the app is the most interesting -- it offers
// a launchpad into the other demonstrations in this example application.
return new LaunchpadSectionFragment();
case 1:
return new BluetoothClass();
default:
// The GPS section of the app .
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
}
}
In this case each fragment for me represented a class, which was implemented in a separate tab and each tab had a separate functionality. One of the key advantages of fragments is you can run separate activities without first letting one activity complete.
Furthermore each fragment is an extension of the java.lang.Object library. So it has all those functions + additional ones. I would read this as well. Lastly it would be a good idea to have separate xml files for each fragment then you can display that separately when a fragment is invoked.
Some more code
Each fragment will/could have this
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
// Do stuff on creation. This is usually where you add the bulk of your code. Like clickListners
View rootview = inflater.inflate(R.layout.xml_the_fragment_uses container,false);
rootview.findViewById(R.id.your_id).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do something
}
});
}
public void onStart(){
super.onStart();
Toast.makeText(getActivity(), "Fragment started",Toast.LENGTH_SHORT).show();
}
public void onResume(){
super.onStart();
Toast.makeText(getActivity(), "Fragment Resumed",Toast.LENGTH_SHORT).show();
}
public void onStop(){
super.onStart();
Toast.makeText(getActivity(), "Fragment Stoped",Toast.LENGTH_SHORT).show();
disableBT();
}
Remember these functions are from the fragment life-cycle I mentioned earlier.
Hopefully that gave you some idea on fragments. Also remember to read this as a lot of functionality uses the v7 app compat library. Including the fragment manager.
By following this guide, http://wptrafficanalyzer.in/blog/adding-drop-down-navigation-to-action-bar-in-android/
I was able to add my drop down navigation bar. The click events and everything function. Now, how do I make it so once an option is selected, it navigates to a different screen with its own layout and different functions.
Any help would be great, thanks in advance!
Edit: This is what I have. My app runs for about a millisecond, and I can see a glimpse "Hello World" and then it crashes. I'm using Sherlock by the way, if that matters.
package com.poe.statcalc;
import com.actionbarsherlock.app.SherlockActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
public class MainActivity extends SherlockActivity {
/** An array of strings to populate dropdown list */
String[] actions = new String[] {
"Bookmark",
"Subscribe",
"Share",
"Something"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** Create an array adapter to populate dropdownlist */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.sherlock_spinner_item, actions);
/** Enabling dropdown list navigation for the action bar */
getSupportActionBar().setNavigationMode(com.actionbarsherlock.app.ActionBar.NAVIGATION_MODE_LIST);
/** Defining Navigation listener */
ActionBar.OnNavigationListener navigationListener = new OnNavigationListener() {
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
switch(itemPosition) {
case 0:
Intent i = new Intent(MainActivity.this, SecondActivity.class);
startActivity(i);
break;
case 1:
//...
break;
}
return false;
}
};
/** Setting dropdown items and item navigation listener for the actionbar */
getSupportActionBar().setListNavigationCallbacks(adapter, navigationListener);
adapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
}
#Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
getSupportMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}
}
You need to maniputate your ArrayAdapter if you want to change the elements, but I don't think you you can use the ArrayAdapter<String> class for that porouse. You may need to use something else than string.
For handling clicks you need to change the onNavigationItemSelected function:
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
switch(itemPosition) {
case 0:
Intent i = new Intent(this, SecondActivity.class);
startActivity(i);
break;
case 1:
// ...
break;
}
return false;
}
You have to start a new Activity by calling startActivity(Intent) in the onNavigationItemSelected callback.
Don't know if this is the exact problem you had (though it sounds like it!), but beware using startActivity from a spinner: it can be called during onCreate().
onNavigationItemSelected in ActionBar is being called at startup how can avoid it?
I want to enable the home button in my fragment. This question is asked earlier but for an activity.
I tried ...
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
... but this doesn't work.
Here is my code:
import com.actionbarsherlock.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.MenuItem;
import android.support.v4.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
public class SafanTab extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.safantab, container, false);
}
public OnClickListener onOverClick = new OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), Over_Safan.class);
startActivityForResult(myIntent, 0);
}
};
public OnClickListener onProductenClick = new OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), Over_Safan.class);
startActivityForResult(myIntent, 0);
}
};
public OnClickListener onTwitterClick = new OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), Over_Safan.class);
startActivityForResult(myIntent, 0);
}
};
}
How can you enable a home button on SherlockFragment?
You also need to override the options menu selection:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Keep in mind, the code above would run in an activity (hence finish()). If you don't use an Activity (which would be odd to me...), then you'll need to replace that.
Have you tried adding the below code the main Activity - the one that extends SherlockActivity or extends SherlockFragmentActivity?
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
I don't think you can getSupportActionBar in something that only extends SherlockFragment.
The simplest solution is to follow these three simple steps:
1 - Declare in the AndroidManifest which is the parent of your activity:
<activity android:theme="#style/Theme.MyApp"
android:name="com.example.CurrentActivity"
android:parentActivityName="com.example.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.ParentActivity" />
2 - Add the Up icon in the action bar, simply calling from your onCreate method:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
3 - Specify the activity to open when the user presses the Up button:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
NOTE:
If you call (as suggested by #Eric):
finish();
instead of:
NavUtils.navigateUpFromSameTask(this);
your are not really performing "up navigation", since as the documentation says:
Up navigation is distinct from the back navigation provided by the system Back button. The Back button is used to navigate in reverse chronological order through the history of screens the user has recently worked with. It is generally based on the temporal relationships between screens, rather than the app's hierarchy structure (which is the basis for up navigation).