Fragments ViewPages and Animations - android

I am working on a ViewPager whose elements can be flipped, as in the CardFlipActivity of android animations demo.
I am having a problem with the beginTransaction() method.
The only quick fix options I get ask me to change the type of frag from android.support.v4.app.Fragment to android.app.Fragment
When I do so, another error comes up and I have to change the type back to support.v4.app.Fragment.
How do I proceed ?
I am using all support.v4 library imports in my code for fragments and viewPagers.
Code:
package com.example.flag_o;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class QuizGame extends FragmentActivity
implements FragmentManager.OnBackStackChangedListener {
static DataClass dc;
static int numQues;
static int quizLev;
static int FLIP_FOR_MAP = 1;
static int FLIP_FOR_INFO = 2;
static int frag_status=0;
static int questions[] = null;
MenuItem map;
MenuItem ques;
private Handler mHandler = new Handler();
private boolean mShowingBack = false;
QuizPagerAdapter quizAdapter;
ViewPager quizPager;
static String RETRIEVE_POS = "position";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_pager);
dc = new DataClass();
numQues = getIntent().getExtras().getInt("numQ");
quizLev = getIntent().getExtras().getInt("level");
java.util.List<Integer> randNums = new java.util.ArrayList<Integer>(dc.flags.length);
for (int i = 0; i <= dc.flags.length; i++)
{
randNums.add(new Integer(i));
}
java.util.Collections.shuffle(randNums);
for(int i=0;i<numQues;i++)
questions[i] = randNums.get(i);
quizAdapter = new QuizPagerAdapter(getSupportFragmentManager(),questions);
quizPager = (ViewPager) findViewById(R.id.quizPager);
quizPager.setAdapter(quizAdapter);
if (savedInstanceState == null) {
// If there is no saved instance state, add a fragment representing the
// front of the card to this activity. If there is saved instance state,
// this fragment will have already been added to the activity.
getFragmentManager()
.beginTransaction()
.add(R.id.container, new FlagFragment())
.commit();
} else {
mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Add either a "photo" or "finish" button to the action bar, depending on which page
// is currently selected.
map = menu.add(Menu.NONE, R.id.action_map, Menu.NONE,
mShowingBack
? R.string.action_photo
: R.string.action_map);
map.setIcon(mShowingBack
? R.drawable.ic_action_photo
: android.R.drawable.ic_menu_mapmode);
map.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
ques = menu.add(Menu.NONE, R.id.action_ques, Menu.NONE,
mShowingBack
? R.string.action_photo
: R.string.action_ques);
ques.setIcon(mShowingBack
? R.drawable.ic_action_photo
: android.R.drawable.ic_menu_help);
ques.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Navigate "up" the demo structure to the launchpad activity.
// See http://developer.android.com/design/patterns/navigation.html for more.
//NavUtils.navigateUpTo(this, new Intent(this, MainActivity.class));
frag_status=0;
return true;
case R.id.action_map:
if(mShowingBack)
frag_status=0;
else
frag_status=1;
flipCard(FLIP_FOR_MAP);
return true;
case R.id.action_info:
if(mShowingBack)
frag_status=0;
else
frag_status=2;
flipCard(FLIP_FOR_INFO);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
switch(frag_status)
{
case 1:
map.setVisible(true);
ques.setVisible(false);
break;
case 2:
map.setVisible(false);
ques.setVisible(true);
break;
}
return super.onPrepareOptionsMenu(menu);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
map.setVisible(true);
ques.setVisible(true);
}
private void flipCard(int flipType) {
if (mShowingBack) {
getFragmentManager().popBackStack();
return;
}
mShowingBack = true;
Fragment mapFrag;
InfoFragment infoFrag;
Bundle args = new Bundle();
args.putInt(RETRIEVE_POS, questions[quizPager.getCurrentItem()]);
switch(flipType) {
case 1 :
mapFrag = new Fragment();
mapFrag.setArguments(args);
getFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, mapFrag)
.addToBackStack(null)
.commit();
break;
case 2 :
frag = new InfoFragment();
frag.setArguments(args);
getFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, frag)
.addToBackStack(null)
.commit();
break;
}
mHandler.post(new Runnable() {
#Override
public void run() {
invalidateOptionsMenu();
}
});
}
#Override
public void onBackStackChanged() {
mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
// When the back stack changes, invalidate the options menu (action bar).
invalidateOptionsMenu();
}
public static class FlagFragment extends Fragment {
int position;
Bundle args;
public FlagFragment() {
position = args.getInt(RETRIEVE_POS);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.pic_fragment, container, false);
ImageView flipImg = (ImageView)rootView.findViewById(R.id.flipFlagImage);
try {
flipImg.setImageResource(dc.flags[position]);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rootView;
}
}
public static class MapFragment extends Fragment {
int position;
Bundle args;
public MapFragment() {
position = args.getInt(RETRIEVE_POS);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.map_fragment, container, false);
ImageView flipImg = (ImageView)rootView.findViewById(R.id.flipMapImage);
try {
flipImg.setImageResource(dc.ortho[position]);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rootView;
}
}
public static class InfoFragment extends Fragment {
public InfoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.info_fragment, container, false);
}
}
public class QuizPagerAdapter extends FragmentStatePagerAdapter {
int fragDet[];
Fragment frag;
Bundle args;
public QuizPagerAdapter(FragmentManager fragmentManager, int [] q) {
super(fragmentManager);
fragDet = q;
}
#Override
public Fragment getItem(int i) {
frag = new FlagFragment();
args.putInt(RETRIEVE_POS, fragDet[i]);
frag.setArguments(args);
return frag;
}
#Override
public int getCount() {
return numQues;
}
#Override
public CharSequence getPageTitle(int position) {
String title = null;
switch(position)
{
case 0 : title = "Paired Devices";
break;
case 1 : title = "Chats";
break;
case 2 : title = "New Devices";
break;
}
return (CharSequence)title;
}
}
}

The support library's Fragment class doesn't support animations in transactions.
Its a trade off between animating or building the app for devices with API higher than 11.
http://developer.android.com/reference/android/app/FragmentTransaction.html
Another way about this is to use the NineOldAndroids library from Jake Wharton and code the transaction yourself.

Related

Button will not work inside Fragment

So my problem is that the buttons that are contained within my fragments throw up an error "Unhandled Exception - Object reference not set to an instance of an object"
I thought because I had referenced the layout that contains the button that this would not cause an error. If anyone could shed some light to what I am doing wrong that would be great. I think I am either missing some vital code or have completely messed it up as I am new to using fragments and understand that they work differently from activities.
This is my MainActivity:
public class MainActivity : ActionBarActivity
{
private SupportToolbar mToolbar;
private MyActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mLeftDrawer;
private HomeFragment mHomeFragment;
private LogInFragment mLogInFragment;
private MatchCentreFragment mMatchCentreFragment;
private PrevCompFragment mPrevCompFragment;
private PrevFixFragment mPrevFixFragment;
private SettingsFragment mSettingsFragment;
private SocialFragment mSocialFragment;
private UpcomCompFragment mUpcomCompFragment;
private UpcomFixFragment mUpcomFixFragment;
private SupportFragment mCurrentFragment = new SupportFragment();
private Stack<SupportFragment> mStackFragments;
private ArrayAdapter mLeftAdapter;
private List<string> mLeftDataItems;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
mToolbar = FindViewById<SupportToolbar>(Resource.Id.toolbar);
mDrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
mLeftDrawer = FindViewById<ListView>(Resource.Id.left_drawer);
mHomeFragment = new HomeFragment();
mLogInFragment = new LogInFragment();
mMatchCentreFragment = new MatchCentreFragment();
mPrevCompFragment = new PrevCompFragment();
mPrevFixFragment = new PrevFixFragment();
mSettingsFragment = new SettingsFragment();
mSocialFragment = new SocialFragment();
mUpcomCompFragment = new UpcomCompFragment();
mUpcomFixFragment = new UpcomFixFragment();
mStackFragments = new Stack<SupportFragment>();
mLeftDrawer.Tag = 0;
SetSupportActionBar(mToolbar);
mLeftDataItems = new List<string>();
mLeftDataItems.Add("Home");
mLeftDataItems.Add("Log In");
mLeftDataItems.Add("Match Centre");
mLeftDataItems.Add("Previous Fixtures");
mLeftDataItems.Add("Upcoming Fixtures");
mLeftDataItems.Add("Previous Competitions");
mLeftDataItems.Add("Upcoming Competitions");
mLeftDataItems.Add("Settings");
mLeftDataItems.Add("Social");
mLeftAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, mLeftDataItems);
mLeftDrawer.Adapter = mLeftAdapter;
mLeftDrawer.ItemClick += MenuListView_ItemClick;
mDrawerToggle = new MyActionBarDrawerToggle(this, mDrawerLayout, Resource.String.openDrawer, Resource.String.closeDrawer);
if (bundle != null)
{
if (bundle.GetString("DrawerState") == "Opened")
{
SupportActionBar.SetTitle(Resource.String.openDrawer);
}
else
{
SupportActionBar.SetTitle(Resource.String.closeDrawer);
}
}
else
{
SupportActionBar.SetTitle(Resource.String.closeDrawer);
}
Android.Support.V4.App.FragmentTransaction trans = SupportFragmentManager.BeginTransaction();
trans.Add(Resource.Id.fragmentContainer, mHomeFragment);
trans.Add(Resource.Id.fragmentContainer, mLogInFragment);
trans.Hide(mLogInFragment);
trans.Add(Resource.Id.fragmentContainer, mMatchCentreFragment);
trans.Hide(mMatchCentreFragment);
trans.Add(Resource.Id.fragmentContainer, mPrevFixFragment);
trans.Hide(mPrevFixFragment);
trans.Add(Resource.Id.fragmentContainer, mUpcomFixFragment);
trans.Hide(mUpcomFixFragment);
trans.Add(Resource.Id.fragmentContainer, mPrevCompFragment);
trans.Hide(mPrevCompFragment);
trans.Add(Resource.Id.fragmentContainer, mUpcomCompFragment);
trans.Hide(mUpcomCompFragment);
trans.Add(Resource.Id.fragmentContainer, mSettingsFragment);
trans.Hide(mSettingsFragment);
trans.Add(Resource.Id.fragmentContainer, mSocialFragment);
trans.Hide(mSocialFragment);
mCurrentFragment = mHomeFragment;
trans.Commit();
}
void MenuListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
Android.Support.V4.App.Fragment fragment = null;
switch (e.Id)
{
case 0:
ShowFragment(mHomeFragment);
break;
case 1:
ShowFragment(mLogInFragment);
break;
case 2:
ShowFragment(mMatchCentreFragment);
break;
case 3:
ShowFragment(mPrevFixFragment);
break;
case 4:
ShowFragment(mUpcomFixFragment);
break;
case 5:
ShowFragment(mPrevCompFragment);
break;
case 6:
ShowFragment(mUpcomCompFragment);
break;
case 7:
ShowFragment(mSettingsFragment);
break;
case 8:
ShowFragment(mSocialFragment);
break;
}
mDrawerLayout.CloseDrawers();
mDrawerToggle.SyncState();
}
private void ShowFragment (SupportFragment fragment)
{
if (fragment.IsVisible)
{
return;
}
var trans = SupportFragmentManager.BeginTransaction();
fragment.View.BringToFront();
mCurrentFragment.View.BringToFront();
trans.Hide(mCurrentFragment);
trans.Show(fragment);
trans.AddToBackStack(null);
mStackFragments.Push(mCurrentFragment);
trans.Commit();
mCurrentFragment = fragment;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
//The hamburger icon was clicked which means the drawer toggle will handle the event
mDrawerToggle.OnOptionsItemSelected(item);
return true;
case Resource.Id.action_refresh:
//Refresh
return true;
case Resource.Id.action_help:
return true;
default:
return base.OnOptionsItemSelected(item);
}
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.drawer_menu, menu);
return base.OnCreateOptionsMenu(menu);
}
protected override void OnSaveInstanceState(Bundle outState)
{
if(mDrawerLayout.IsDrawerOpen((int)GravityFlags.Left))
{
outState.PutString("DrawerState", "Opened");
}
else
{
outState.PutString("DrawerState", "Closed");
}
base.OnSaveInstanceState(outState);
}
protected override void OnPostCreate(Bundle savedInstanceState)
{
base.OnPostCreate(savedInstanceState);
mDrawerToggle.SyncState();
}
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
mDrawerToggle.OnConfigurationChanged(newConfig);
}
}
}
This is one of my fragments (there are several but they all contain basically the same code so far)
public class PrevFixFragment : Android.Support.V4.App.Fragment
{
Button button;
public PrevFixFragment()
{
}
public static Android.Support.V4.App.Fragment newInstance(Context context)
{
PrevFixFragment fragment = new PrevFixFragment();
return fragment;
}
public override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.PreviousFixtures, null);
button = View.FindViewById<Button>(Resource.Id.upcombutton);
button.Click += StartNewActivity;
return view;
}
void StartNewActivity(object sender, EventArgs e)
{
Intent intent = new Intent(Activity, typeof(UpcomFixActivity));
StartActivity(intent);
}
}
}
Try moving the following lines to override void OnViewCreated or override void onActivityCreated
button = View.FindViewById<Button>(Resource.Id.upcombutton);
button.Click += StartNewActivity;
You must write View with lowercase view in statement below:
button = View.FindViewById<Button>(Resource.Id.upcombutton);

Implement back navigation with DrawerLayout and AppCompatActivity without DrawerToggle

I've been searching and thinking how to implement the desire behaviour that I want when switching back and forth between fragments when using a Navigation Drawer. Actually the documentation says:
When using fragments in your app, individual FragmentTransaction objects may represent context changes that should be added to the back stack. For example, if you are implementing a master/detail flow on a handset by swapping out fragments, you should ensure that pressing the Back button on a detail screen returns the user to the master screen
So in my app I have a MainActivity that controls everything and a navigation layout within you can change between predefined options. This is the view when you launch the app
When you click on an item in the navigation drawer it opens a new fragment that replaces the main_content as follows:
At this point the behaviour is the correct one, so if you want to change the options you need to open the navigation drawer again to toggle between the menu options.
This is the Main Activity (notice that there is no Drawer Toggle)
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout drawerLayout;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSnackBarView = findViewById(R.id.myCoordinatorLayout);
setToolbar(); // Set Toolbar como action bar
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
setupDrawerContent(navigationView);
}
drawerTitle = getResources().getString(R.string.app_name);
if (savedInstanceState == null) {
selectItem(drawerTitle, mCurrentSelectedPosition);
}
}
private void setToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
if (ab != null) {
// Poner ícono del drawer toggle
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
}
}
private void setupDrawerContent(final NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Marcar item presionado
menuItem.setChecked(true);
// Crear nuevo fragmento
String title = menuItem.getTitle().toString();
int id = menuItem.getItemId();
selectItem(title, id);
return true;
}
}
);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!drawerLayout.isDrawerOpen(GravityCompat.START)) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private void selectItem(String title, int id) {
Bundle args = new Bundle();
args.putString(PlaceholderFragment.ARG_SECTION_TITLE, title);
Fragment fragment = PlaceholderFragment.newInstance(title);
fragment.setArguments(args);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
switch (id) {
case R.id.nav_localizacion:
//Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 0;
LocalizacionFragment fragment_localizacion = new LocalizacionFragment();
// fragmentManager = getSupportFragmentManager();
Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_localizacion)
.commit();
break;
case R.id.nav_productos:
Snackbar.make(mSnackBarView, R.string.menu_productos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 1;
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
break;
case R.id.nav_consejos:
Snackbar.make(mSnackBarView, R.string.menu_consejos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 3;
ConsejosFragment fragment_consejo = new ConsejosFragment();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_consejo)
.commit();
break;
default:
break;
}
drawerLayout.closeDrawers(); // Cerrar drawer
setTitle(title); // título actual
}
}
I don't use the hamburger icon because it hides under the Navigation Layout, but here is the thing. When you click on "Recetas" in the recycle view it open a new fragment (replace) but now I want to show the up caret icon and give proper back navigation to my app.
Here is the code of the "Consejos" fragment class
Consejos.java
public class ConsejosFragment extends Fragment {
RecyclerView mRecycler;
ConsejosAdapter mAdapter;
FragmentActivity mActivity;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = (FragmentActivity) activity;
setRetainInstance(true);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
List items = new ArrayList();
items.add(new ConsejosInfo("Recetas", R.drawable.icon_recetas));
/* Inflamos el layout */
View v = inflater.inflate(R.layout.consejos_layout_recycler, container, false);
/* Obtenemos el Recycle */
mRecycler = (RecyclerView) v.findViewById(R.id.recycler_consejos);
/* Creamos el adaptador */
mAdapter = new ConsejosAdapter(mActivity, items);
/* Set click en adapter */
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecycler.setHasFixedSize(true);
mRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecycler.setAdapter(mAdapter);
}
}
And this is the adapter that the Recyclerview use and handles the click on the item inside:
Adapter.java
public class ConsejosAdapter extends RecyclerView.Adapter<ConsejosAdapter.ConsejosViewHolder> {
private List<ConsejosInfo> _items = new ArrayList<ConsejosInfo>();
private final FragmentActivity mActivity;
private Context context;
public ConsejosAdapter(FragmentActivity mActivity, List<ConsejosInfo> items) {
this._items = items;
this.mActivity = mActivity;
}
#Override
public int getItemCount() {
return _items.size();
}
#Override
public ConsejosViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardview_consejos, viewGroup, false);
return new ConsejosViewHolder(v);
}
#Override
public void onBindViewHolder(ConsejosViewHolder viewHolder, int position) {
viewHolder.imagen.setImageResource(_items.get(position).get_imagen());
viewHolder.nombre.setText(_items.get(position).get_nombre());
}
public class ConsejosViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imagen;
public TextView nombre;
public ConsejosViewHolder(final View itemView) {
super(itemView);
imagen = (ImageView) itemView.findViewById(R.id.consejos_imagen);
nombre = (TextView) itemView.findViewById(R.id.consejos_nombre);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
RecetasFragment recetasFragment = new RecetasFragment();
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, recetasFragment)
.addToBackStack(null)
.commit();
}
}
}
In the Consejos Adapter I added to backstack the fragment before calling the new fragment (inside fragment) and that changes the behaviour of the back button, so before this if you press the back button is closes the app but now it takes you to the Consejos fragment, but now I want to add the up caret and make the exactly same operation as when you click the back button but I don't know how to achieve it.
Please feel free to ask for more code
Thank you very much
I will give you the full answer:
We will use the interfaces to communicate with the MainActivity from RecetasFragment so we can enable and disable navigation back button.
RecetasFragment class:
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by hema on 8/19/2015.
*/
public class RecetasFragment extends Fragment {
private CommunicateWithActivity mWithActivity;
public RecetasFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mWithActivity = (CommunicateWithActivity) activity; // MainActivity must implement CommunicateWithActivity interface.
mWithActivity.enableNavigationBack(true); // We enable navigation back here.
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement CommunicateWithActivity");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recetas, container, false);
}
#Override
public void onDestroy() {
super.onDestroy();
mWithActivity.enableNavigationBack(false); // We disable navigation back here, restore menu icon.
}
public interface CommunicateWithActivity {
void enableNavigationBack(boolean enable);// we will implement this method in MainActivity class.
}
}
And in MainActivity class we will implement CommunicateWithActivity interface, Modify your MainActivity class (only required modifications):
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity implements RecetasFragment.CommunicateWithActivity {
private Toolbar mToolbar;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mToolbar.setNavigationIcon(R.drawable.ic_menu);
mSnackBarView = findViewById(R.id.myCoordinatorLayout);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
setupDrawerContent(navigationView);
}
drawerTitle = getResources().getString(R.string.app_name);
if (savedInstanceState == null) {
selectItem(drawerTitle, mCurrentSelectedPosition);
}
}
private void setupDrawerContent(final NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Marcar item presionado
menuItem.setChecked(true);
// Crear nuevo fragmento
String title = menuItem.getTitle().toString();
int id = menuItem.getItemId();
selectItem(title, id);
return true;
}
}
);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!drawerLayout.isDrawerOpen(GravityCompat.START)) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private void selectItem(String title, int id) {
Bundle args = new Bundle();
args.putString(PlaceholderFragment.ARG_SECTION_TITLE, title);
Fragment fragment = PlaceholderFragment.newInstance(title);
fragment.setArguments(args);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
switch (id) {
case R.id.nav_localizacion:
//Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 0;
LocalizacionFragment fragment_localizacion = new LocalizacionFragment();
// fragmentManager = getSupportFragmentManager();
Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_localizacion)
.commit();
break;
case R.id.nav_productos:
Snackbar.make(mSnackBarView, R.string.menu_productos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 1;
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
break;
case R.id.nav_consejos:
Snackbar.make(mSnackBarView, R.string.menu_consejos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 3;
ConsejosFragment fragment_consejo = new ConsejosFragment();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_consejo)
.commit();
break;
default:
break;
}
drawerLayout.closeDrawers(); // Cerrar drawer
setTitle(title); // título actual
}
#Override
public void enableNavigationBack(boolean enable) {
if(enable) {
// We enable the navigation back button here
mToolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// On navigation back button clicked.
if(getSupportFragmentManager().getBackStackEntryCount() > 0) { // Check if there is fragments in BackStack.
getSupportFragmentManager().popBackStack(); // PopBackStack.
} else {
// You can implement this part as you want.
return;
}
}
});
} else {
mToolbar.setNavigationIcon(R.drawable.ic_menu);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(drawerLayout != null) {
drawerLayout.openDrawer(Gravity.LEFT);
}
}
});
}
}
}
Please let me know if there is something you don't understand.

One Fragment inside ViewPager doesn't show up

I have a Tabbed Activity hosting a viewpager (auto-generated with eclipse wizard). I slightly modified just the auto generated FragmentPagerAdapter in order to instantiate a specific fragment on each tab. Initially i had 4 tab, 3 fragments for the first tabs and still the auto generated placeholder in the last one, and they worked. When i replaced the last placeholder with an instance of one of my Fragment i faced the following problem: the fragment in one of the last two tabs stays blank, as follow:
_____1st TAB___|____2nd TAB_|___3rd TAB_____|____4th TAB____|
[MasterFragment][RequestMap][MasterFragment][MasterFragment]
This stays blank_____________________|
Moreover, if i make a "random" sequence of actions (change tabs, click on the buttons to perform some actions,...) the fragment that doesn't show up swaps, and becomes the last one as follow:
_____1st TAB___|____2nd TAB_|___3rd TAB_____|____4th TAB____|
[MasterFragment][RequestMap][MasterFragment][MasterFragment]
This stays blank__________________________________|
Here's the code for my FragmentPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case REQUEST_TAB:
masterFragment = new MasterFragment(MasterFragment.ALL_REQUEST);
return masterFragment;
case MAP_TAB:
requestMap = new RequestMap();
return requestMap;
case OWNER_TAB:
masterFragmentOwner = new MasterFragment(MasterFragment.OWNER_REQUEST);
System.out.println("I should have created the Owner MasterFragment");
return masterFragmentOwner;
case JOINED_TAB:
masterFragmentJoined = new MasterFragment(MasterFragment.JOINED_REQUEST);
return masterFragmentJoined;
}
return null;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case REQUEST_TAB:
return getString(R.string.request_tab_title).toUpperCase(l);
case MAP_TAB:
return getString(R.string.map_tab_title).toUpperCase(l);
case OWNER_TAB:
return getString(R.string.owner_tab_title).toUpperCase(l);
case JOINED_TAB:
return getString(R.string.joined_tab_title).toUpperCase(l);
default:
return "";
}
}
}
I omit the code regarding the setup of the viewPager because is the same auto generated from the eclipse wizard. While here's the code for the MasterFragment class:
package it.polimi.frontend.fragment;
import it.polimi.appengine.entity.manager.model.Request;
import it.polimi.appengine.entity.manager.model.User;
import it.polimi.frontend.activity.R;
import it.polimi.frontend.util.QueryManager;
import it.polimi.frontend.util.QueryManager.OnRequestLoadedListener;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MasterFragment extends Fragment implements OnRequestLoadedListener, RequestList.OnRequestSelectedListener, RequestDetail.OnUserClickedListener{
private boolean twoPane;
private static View view;
public final static int ALL_REQUEST=0;
public final static int OWNER_REQUEST=1;
public final static int JOINED_REQUEST=2;
private int mode;
public MasterFragment(){
this.mode=0;
}
public MasterFragment(int mode){
this.mode=mode;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
QueryManager.getInstance().addListener(this);
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.fragment_master,container, false);
List<Request> requests = new ArrayList<Request>();
RequestList requestListFragment = null;
switch (mode) {
case OWNER_REQUEST:
requests = QueryManager.getInstance().getCurrentUser().getRequests();
System.out.println("Dovrei aver recuperato le richieste dell'owner");
break;
case JOINED_REQUEST:
String mail=null;
if (QueryManager.getInstance().getCurrentUser()!=null){
User current =QueryManager.getInstance().getCurrentUser();
mail = current.getPwAccount() != null ?
current.getPwAccount()
: current.getGmailAccount() != null ?
current.getGmailAccount()
: current.getFbAccount() != null ?
current.getFbAccount()
: null;
requests = QueryManager.getInstance().getUserPartecipation(mail);
}
else
requests = new ArrayList<Request>();
break;
default: //ALL_REQUEST case and all the other possibilities
requests = QueryManager.getInstance().getRequests();
break;
}
requestListFragment = new RequestList(requests, mode);
if (view.findViewById(R.id.detail_container) != null) {//TABLET CASE
twoPane = true;
getChildFragmentManager().beginTransaction()
.replace(R.id.request_list_container,requestListFragment,RequestList.ID)
.commit();
} else { //PHONE CASE:
getChildFragmentManager().beginTransaction()
.replace(R.id.container,requestListFragment,RequestList.ID)
.commit();
}
} catch (InflateException e) {
// is already there, just return view as it is
e.printStackTrace();
}
return view;
}
#Override
public void onRequestSelected(int position, Request request) {
if (twoPane) {
DetailContainerFragment detailContFrag = new DetailContainerFragment(request,mode);
getChildFragmentManager().beginTransaction()
.replace(R.id.detail_container, detailContFrag, DetailContainerFragment.ID).commit();
} else {
switch (mode) {//This empty switch if for future changes
case OWNER_REQUEST:
break;
case JOINED_REQUEST:
break;
default://ALL_REQUEST
break;
}
RequestDetail fragment = new RequestDetail(request,mode);
Fragment reqList=getChildFragmentManager().findFragmentByTag(RequestList.ID);
getChildFragmentManager().beginTransaction()
.hide(reqList)
.addToBackStack(RequestDetail.ID)
.add(R.id.container,fragment,RequestDetail.ID)
.commit();
}
}
#Override
public void onUserClicked(User user,String requestId) {
if (!twoPane) {
FeedbackDetail fragment = new FeedbackDetail(user,this.mode,requestId);
Fragment reqDetail=getChildFragmentManager().findFragmentByTag(RequestDetail.ID);
getChildFragmentManager().beginTransaction()
.hide(reqDetail)
.addToBackStack(FeedbackDetail.ID)
.add(R.id.container,fragment,FeedbackDetail.ID)
.commit();
} else {
/*DetailContainerFragment should take care of it*/
}
}
#Override
public void onRequestLoaded(List<Request> requests) {
System.out.println("Ho caricato: "+requests.size());
RequestList requestListFragment = (RequestList)getChildFragmentManager().findFragmentByTag(RequestList.ID);
switch (mode) {//Also this switch is for future changes, but the requests list is anyway fetched and assigned to RequestList above
case OWNER_REQUEST:
//TODO
break;
case JOINED_REQUEST:
//TODO
break;
default: //ALL_REQUEST
if (requestListFragment!=null)
requestListFragment.setRequestAdapter(requests);
break;
}
}
}
If i'm missing something important please, let me know.
Thank you all in advance
EDIT:
I forgot to say that the System.out that i placed show up in the console, so the "blank" fragment should have been created, and it should have passed through his onCreateView().
I found the bug. The problem was
private static View view;
because of the static properties. Removing "static" it worked again. Actually i can't explain even now how it could have worked for a while on the first and last tabs and not in the third, because the static attributes should be shared among all instances of the class. Because of the internals of the ViewPager the problem seemed to show up only on adjacent identical MasterFragment, if they where interleaved with any other fragment it worked.

Android refresh a fragment list from its parent activity

I have a main activity which contains the action bar with 3 menu buttons in it.
I then have a fragment within this main activity which has a list.
I would like to be able to refresh the list in the fragment from the main activity, when one of the menu buttons is clicked, or preferably just removed all the rows from the list.
Any help is appreciated.
Thanks.
public class Favourite extends SherlockFragmentActivity {
ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favourite);
actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
BitmapDrawable bg = (BitmapDrawable)getResources().getDrawable(R.drawable.actionbar_bg);
bg.setTileModeX(TileMode.REPEAT);
getSupportActionBar().setBackgroundDrawable(bg);
getSupportActionBar().setIcon(R.drawable.favourite_title);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabAll = actionBar.newTab();
ActionBar.Tab tabfavs = actionBar.newTab();
ActionBar.Tab tabhist = actionBar.newTab();
tabAll.setText("all");
tabfavs.setText("favs");
tabhist.setText("hist");
tabAll.setTabListener(new MyTabListener());
tabfavs.setTabListener(new MyTabListener());
tabhist.setTabListener(new MyTabListener());
actionBar.addTab(tabAll);
actionBar.addTab(tabfavs);
actionBar.addTab(tabhist);
try{
}
catch(Exception e)
{
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.actionbar_itemlist_favourite, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.history:
break;
case R.id.favourite:
Intent favAct = new Intent(this, Favourite.class);
startActivity(favAct);
break;
case R.id.delete:
///I WANT TO BE ABLE TO REFRESH FRAGMENTLIST FROM HERE
}
return true;
}
}
class MyTabListener implements ActionBar.TabListener {
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(tab.getPosition()==0)
{
FavouriteAllWords frag = new FavouriteAllWords();
ft.replace(android.R.id.content, frag);
}
else if(tab.getPosition()==1)
{
FavouriteFavWords frag = new FavouriteFavWords();
ft.replace(android.R.id.content, frag);
}
else if(tab.getPosition()==2)
{
FavouriteHistWords frag = new FavouriteHistWords();
ft.replace(android.R.id.content, frag);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
////////////////////MY LIST FRAGMENT CLASS
public class FavouriteAllWords extends ListFragment {
ArrayAdapter<String> adapter;
List<String> stringOfFavWords;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
adapter = new ArrayAdapter<String>(
inflater.getContext(), R.layout.row, stringOfFavWords);
setListAdapter(adapter);
return super.onCreateView(inflater, group, saved);
}
#Override
public void onActivityCreated (Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
}
You can easily achieve this using INTERFACE
MainActivity.java
public class MainActivity extends Activity {
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
private FragmentRefreshListener fragmentRefreshListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button)findViewById(R.id.btnRefreshFragment);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(getFragmentRefreshListener()!=null){
getFragmentRefreshListener().onRefresh();
}
}
});
}
public interface FragmentRefreshListener{
void onRefresh();
}
}
MyFragment.java
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = null; // some view
/// Your Code
((MainActivity)getActivity()).setFragmentRefreshListener(new MainActivity.FragmentRefreshListener() {
#Override
public void onRefresh() {
// Refresh Your Fragment
}
});
return v;
}
}
Just make your update/refresh method public and call it from your Activity.
OR
Use LocalBroadcastManager or EventBus to send event from your Activity, and by subscribing to this event in a Fragment - react to it and call refresh/update method.
Your activity can call methods in the fragment by acquiring a reference to the Fragment.
(1) Provide a tag when you add your fragment.
transaction.add(R.id.fragment_container, myFragment, "myfragmentTag");
(2) In your hosting activity you can find the fragment and have access to it's methods.
FragmentManager fm = getSupportFragmentManager();
myFragment f = (myFragment) fm.findFragmentByTag("myfragmentTag");
f.refreshAdapter()
(3) refreshAdapter() could now call adapter.notifyDataSetChanged().
This is one of the recommended ways to communicate up to a fragment.
The interface implementation is mainly for communicating back to the activity.
Biraj Zalavadia's answer is 100% right, you will call nay fragment methods from using interface....
this interface methods is running without error...
use this in MainActivity above oncreate
private FragmentRefreshListener fragmentRefreshListener;
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(
FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
inside of Activity
private void refreshcall(String result2) {
// TODO Auto-generated method stub
if (getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh(result2);
}
}
and put this in needed Fragment
private FragmentRefreshListener fragmentRefreshListener;
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(
FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
Communicating with Other Fragments
http://developer.android.com/training/basics/fragments/communicating.html
This can also be used to communicate between an Activity and a Fragment.
When you click on ActionBar any Button then call interface to refresh the ListFragment. Because in java interface is used for inter-communication.
In Kotlin
Get the list of Support Fragment from the activity and check Instance and then call fragment function
val fragments = supportFragmentManager.fragments
for (fragment in fragments) {
if (fragment is HomeCategoriesFragment) {
fragment.updateAdapter() // Define function in Fragment
}
}

how to swipe between activity (where is my code wrong???)

I have 4 activity that have 4 class & xml layout ; i want to swipe between in 4 activity !!
i use this code from another post (This Post: Fling gesture detection on grid layout)
i want when touching leftToright Or rightToleft swipe with opening new activity.
where is my code is wrong :
my code :
package com.package110.Y;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class ActivitySwipeDetectorActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// how to set this 3 line to in my code Or change or update it
//ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
//lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
//lowestLayout.setOnTouchListener(activitySwipeDetector);
}
public class ActivitySwipeDetector implements View.OnTouchListener {
Intent left = new Intent(getApplicationContext(), left.class);
Intent right = new Intent(getApplicationContext(), right.class);
Intent top = new Intent(getApplicationContext(), top.class);
Intent bottom = new Intent(getApplicationContext(), bottom.class);
static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public ActivitySwipeDetector(Activity activity){
this.activity = activity;
}
public void onRightToLeftSwipe(){
Log.i(logTag, "RightToLeftSwipe!");
activity.startActivity(right);
}
public void onLeftToRightSwipe(){
Log.i(logTag, "LeftToRightSwipe!");
activity.startActivity(left);
}
public void onTopToBottomSwipe(){
Log.i(logTag, "onTopToBottomSwipe!");
activity.startActivity(top);
}
public void onBottomToTopSwipe(){
Log.i(logTag, "onBottomToTopSwipe!");
activity.startActivity(bottom);
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if(Math.abs(deltaX) > MIN_DISTANCE){
// left or right
if(deltaX < 0) { this.onLeftToRightSwipe(); return true; }
if(deltaX > 0) { this.onRightToLeftSwipe(); return true; }
}
else {
Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
// swipe vertical?
if(Math.abs(deltaY) > MIN_DISTANCE){
// top or down
if(deltaY < 0) { this.onTopToBottomSwipe(); return true; }
if(deltaY > 0) { this.onBottomToTopSwipe(); return true; }
}
else {
Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
return true;
}
}
return false;
}
}
}
explain:
my app is force close !!!
my google API is for android 3.0 ; does it have make problem for my app ?
and also i try this code and it force close !!!!
another code :
package ir.package110.Y;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
public class ActivitySwipeDetectorActivity extends Activity {
private GestureDetector gestureDetector;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ...
gestureDetector = new GestureDetector(new SwipeGestureDetector());
}
/* ... */
Intent right = new Intent(ActivitySwipeDetectorActivity.this.getBaseContext(), right.class);
Intent left = new Intent(ActivitySwipeDetectorActivity.this.getBaseContext(), left.class);
private void onLeftSwipe() {
// Do something
startActivity(left);
}
private void onRightSwipe() {
startActivity(right);
// Do something
}
// Private class for gestures
private class SwipeGestureDetector extends SimpleOnGestureListener {
// Swipe properties, you can change it to make the swipe
// longer or shorter and speed
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 200;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
try {
float diffAbs = Math.abs(e1.getY() - e2.getY());
float diff = e1.getX() - e2.getX();
if (diffAbs > SWIPE_MAX_OFF_PATH)
return false;
// Left swipe
if (diff > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
ActivitySwipeDetectorActivity.this.onLeftSwipe();
// Right swipe
} else if (-diff > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
ActivitySwipeDetectorActivity.this.onRightSwipe();
}
} catch (Exception e) {
Log.e("YourActivity", "Error on gestures");
}
return false;
}
}
}
I think the best way to do that is one single Activity and 4 fragments, with a ViewPager.
You can check this link about fragments:
http://androidcookbook.com/Recipe.seam;jsessionid=A2DD7A11C804B7C7646DCA883AA452FC?recipeId=1160
And this one about ViewPager:
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
You should use Fragments. It makes navigation much cleaner.
Fragments run inside of an Activity, and can look and function just like an Activity!
Here is some code.
Activity to hold Fragments
(Tabs and ActionBar can be hidden)
public class Activity extends FragmentActivity implements ActionBar.TabListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.ScoreBoardStyles);
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setCustomView(t)
.setTabListener(this));
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new FirstFragment();
}
if (position == 1) {
fragment = new SecondFragment();
}
if (position == 2) {
fragment = new ThirdFragment();
}
if (position == 3) {
fragment = new FourthFragment();
}
return fragment;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
}
return null;
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
return rootView;
}
}
}
Example of a Fragment
public class FirstFragment extends Fragment {
public ScoreFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.first_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// YOUR CODE HERE
}
}
If you are using AndroidStudio!
Right click your com.blah.bleh
Go to New
Select create new TabbedActivity (Choose your navigation style towards bottom)
Then create your Fragments
Right click your com.blah.bleh
Go to New
Select Fragment and choose your Fragment type
Set the layout in your Activity class here
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new FirstFragment();
}
if (position == 1) {
fragment = new SecondFragment();
}
if (position == 2) {
fragment = new ThirdFragment();
}
if (position == 3) {
fragment = new FourthFragment();
}
return fragment;
}
Hope that helps!

Categories

Resources