Overview
I'm developing a card game. Sometimes though the user may want to start over and create a new game, that's why I thought having a button in a corner that pops up a 'floating' menu where the user has the option to start a new game and quit the current one.
I know how to start over a new game, but I don't know how to make a button appear in every fragment (I have a FragmentManager) capable of making pop up a Menu, possibly a floating one so the user can still see what's behind.
I took a look at this API Guide for Menus but I'm not sure how to use this for my purpose, what do you suggest?
Example
Here's an example of the Menu I'd like to achieve:
All you need is to declare your custom dialog class:
public class CustomDialog extends Dialog {
public CustomDialog(final Context context) {
super(context);
setContentView(R.layout.your_custom_layout);
(...)
}
}
you can start another activities using context passed through constructor etc.
It's not a menu, it's called Dialog in Android. You need to google how to create custom Dialog in Android. You will see lots of tutorials that do this.
Related
I have an Activity that I have already implemented sometime ago.
It involves around making a in app purchase, so all the logic is relatively self contained. it doesn't need to care about anything else.
Now, i wish to make that Activity to optionally show up in a dialog in some other activity. Is there a quick way to do that? I still need to keep the old behavior however, where the activity show up as a regular screen.
So is there someway that I could launch the activity with that make it show up as a dialog?
Thanks
You cant show activity as dialog.
Your options are:
1: Open the other activity with some boolean extra like "showDialog", true
Intent intent = new Intent(this, OtherActivity.class);
intent.putExtra("showDialog", true);
and in the other activity in (for example) onCreate:
Boolean showDialog = getIntent().getExtras().getBoolean("showDialog");
if (showDialog) {
// Code to show dialog
}
2: Create a DialogFragment and show it in your original activity. This custom DialogFragment you can use on both activities
https://guides.codepath.com/android/Using-DialogFragment
Probably your cleanest option depending on how complex your Activity is, is to create a new DialogFragment based on your current activity.
A DialogFragment is basically a Fragment, so has a relatively similar set of lifecycle callbacks to your Activity so it shouldn't be too difficult to re-work as a DialogFragment.
If the in-app purchase framework has specific callback requirements with an Activity then you will need to take that into account.
Another separate option would be to mock the appearance of a Dialog, by creating an Activity that may be transparent around the border of the main content.
Just Inflate the layout one button click on onCreate Method.
WhAT I WILL SUGGEST IS try alert box and in place of normal layout inflate you activity layout .
these might help
The easiest way to do that is to apply a dialog theme to the activity:
<activity android:theme="#style/Theme.AppCompat.Dialog" />
Or in the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_Dialog);
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
}
You can customize parameters of the theme in styles.xml, e.g. dim enabled/disabled, click outside behavior.
The crucial point is to perform setTheme() before super.onCreate(), because Theme is immutable, once set through super.onCreate() it cannot be mutated later.
What I want to do:
I want to have multiple activities each prefaced with a page explaining to the user what the activity is about.
What I'm currently doing:
So my main class BaseModuleActivity extends Activity and I am trying to write a function called showTutorial() which will explain the next steps to the users.
Here is my attempt in doing so:
public void showTutorial(String title, String explanation){
setContentView(R.layout.tutorial_screen);
TextView tv1 = (TextView)findViewById(R.id.tutoTextTitle);
tv1.setText(title);
TextView tv2 = (TextView)findViewById(R.id.tutoTextExplanation);
tv2.setText(explanation);
findViewById(R.id.tutoButton).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
//remove the tutorial's view
findViewById(R.id.tutoLayout).setVisibility(View.GONE);
}
});
}
And this method is called in the following:
public class myFirstActivity extends BaseModuleActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
//First show tuto
super.showTutorial(getString(R.string.upTitle),getString(R.string.upExplanation));
//TODO then actually do the activity stuff
/*
(findViewById(R.id.next_button)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
*/
}
}
Problem:
I think the problem is mainly conceptual. I don't know the best approach to do this and the approach I'm taking is not working.
What I'm doing is not working because the view just become empty. I thought setting the visibility of the linearLayout to gone would make it disappear and the actual activity will able to take place.
What I need:
I need to understand if I can do what I want with my approach or not? Or what approach should I take.
I found some similar questions. However, the answer to these questions didn't seem to fit my problem.
I also looked into layout inflater and fragment, but layout inflater seem to be more for listView and fragment uses layout inflater.
Well, there are some approaches to show a guide for your activity (or application).
First one, and probably the easiest, is to show a dialog/TextView when user enters an activity and explain the activity guide in that dialog/TextView using plain text. From your explanation, I think this one is what your are trying to do.
Second one is to use something like slides with pictures to explain about your activity (like Google Sheets application).
Third one is to explain each control in your activity separatly by highlighting them (similar to how Go Launcher explains its feature on first launch)
You can find more info in below links:
How to implement first launch tutorial like Android Lollipop apps: Like Sheets, Slides app?
Android - first launch interactive tutorial
Seems that what you want is actually an introduction. Take a look at this project:
https://github.com/rubengees/introduction
From each introduction page you can launch the correspondent activity.
I know this is somewhat of a design question but I do have specific questions for it. I'm trying to understand how to handle a situation like this one:
Let's say I have a RecyclerViewFragment which loads a RecyclerView containing a bunch of Toy objects.
In one situation: Maybe this RecyclerViewFragment is part of a ViewPager on main display. There is a FloatingActionButton add-button present over this RecyclerView. You click the + button and you can add a new Toy to the list. Or you can click a Toy from the list directly and a floating menu pops up with Edit/Delete buttons, and pressing Edit lets you edit the Toy's details in a DialogFragment, or clicking Delete removes it from the RecyclerView.
In another situation: Now I am in a separate part of the app where I want to choose toys to use. So I press a button and a DialogFragment appears with a RecyclerView of Toys. I can click a Toy and it'll be added to my cart.
It seems like I should be re-using the same RecyclerView code in both situations, since they both involve a list of the same Toys. The only difference is that in one situation, I can add Toys and edit Toy details, and in the other situation, there is no Add button and clicking on a toy does something different (adding to a cart as opposed to bringing up an Edit/Delete dialog).
Is this the correct way to handle this:
Communication from Fragment to Activity: Interfaces? Have the RecyclerViewFragment, in the onAttach method, assign a listener of my design to the context. Then when a row of the RecyclerView is pressed, the callback is triggered. Now the underlying Activity can decide what to do with that press -- show the Edit/Delete dialog in one situation, add the Toy to a Cart in the other situation. Either way, the click item sends the Toy to the calling Activity so it can decide what to do with it.
Communication from Activity to Fragment: Now what about the situation with the Add button? This Add button would not be intrinsically part of the RecyclerViewFragment, so when I click Add, it would bring up the details dialog box where I can give the Toy details, and then press OK to add it. So somehow I have to transfer this new Toy to the Fragment to have it added to the RecyclerView. Would I simply do something like this:
RecyclerViewFragment recyclerViewFragment = (RecyclerViewFragment ) getSupportFragmentManager().findFragmentByTag("TOY_RECYCLERVIEW");
recyclerViewFragment.getNewToyAndRefreshList(newToy);
and then in the RecyclerViewFragment:
public void getNewToyAndRefreshList(Toy newToy) {
toyList.add(newToy);
Collections.sort(toyList); //Toy has Comparable implemented, sort by name
recyclerViewAdapter.notifyDataSetChanged();
}
Am I on the right track? Is there a different way to fix this situation?
That's certainly a design question, but IMHO there's a very specific issue on it and I believe it's a good question (reason I'm answering), but that also means other developers might have other approaches to solve the issue.
1. that is a totally fair and acceptable approach to it. You let the fragment be simple UI element and let someone else (the activity) implement the click behavior.
For this approach remember to code it only against the interface. That means, don't cast it to your activity. For example:
// do this
toyClickListener.onToyClicked(toy);
// don't do this
((MyActivity)getActivity()).onToyClicked(toy);
That way you keep the "simple UI element" be completely unaware of who is implementing the behavior.
2. IMO for this kind of scenario (specially on RecyclerView.Adapter) the best thing to do is to forget the UI and only focus on the data. And how speciafically you implement this, will vary on what is your data source.
But the base idea is that you have somewhere a data repo (DB?) and anyone using data from there, should subscribe to changes to it.
So you override RecyclerView.Adapter.registerAdapterDataObserver and unregisterAdapterDataObserver add the subscription/listener code, something like that:
#Override registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
super.registerAdapterDataObserver(observer);
db.subscribe(this, toyList);
}
#Override unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
db.unsubscribe(this);
super.unregisterAdapterDataObserver(observer);
}
#Override public void onDbDataUpdate(new Data comes here){
update the data, and call .notifyDataSetChanged();
}
that way once the FAB + and then dialog is clicked the new Toy gets added to the DB and the adapter gets "automatically" notified.
So if this data comes from a SQLite you can call on the cursor registerContentObserver if it's a RealmDB you'll use addChangeListener, even Android databinding libraries have a ObservableList
In my Android application I have a Button which opens up a context menu when clicked. The issue is that if a user clicks quickly, they can open multiple instances of the menu.
b.setOnClickListener( new OnClickListener() {
#Override
public void onClick( View view ) {
// popup options
view.showContextMenu();
}
} );
How can I prevent the user from opening up more than one copy? I am looking for a 'boolean' like checking the Visible status, but can't seem to find anything. My hope was that there was a function somehow that would result in code similar to:
if (context menu is not open)
open context menu
else
don't do anything
I really don't like this UI pattern. It's this sort of thing that cause iOS developers (and users) to think that Android developers lack discipline. Context menus are for long-presses, period. Use something else, like an AlertDialog or PopupMenu, elsewhere.
That being said, set a boolean flag when you show the context menu, checking it first to prevent duplicate menus. Clear the flag in onContextMenuClosed().
On the iPhone I use a Navigation Controller to push and pop Views from. Very handy.
Is there an equivalent in Android?
This is an old question, but I believe the answer has changed. It is now possible to imitate the Nav stack in iOS in android using Fragments.
http://developer.android.com/reference/android/app/Fragment.html
Basically instead of jumping from Activity to Activity you instead stay in one Activity that controls the display, organization, and animation of Fragments which each contain their own behavior much like the NavController / UIViewController model in iOS.
It is also backwards compatible as a static library so you can implement it on pre-Honeycomb devices.
Strategies for Honeycomb & backward compatibility
Typically in android, each view is displayed in its own Activity. You can read about activities in the application fundamentals documentation. To move to a new Activity, or view, you use an intent.
If you haven't done so yet, I'd highly recommend reading through those introductary android docs. They aren't too long, and do a good job of explaning the basic program structure.
I made a Framework (github) to provide a hierarchical navigation pattern, with animations to provide sense of navigation, rather than launching new Activities every time.
Here's how to use it:
Add the framework to your project as a Module
Add a new Java class in your project ("File - New - Java Class").
Note: If you are editing the Activity.java file that provides you the template, delete all its implementations and leave it empty.
Make it extend NavigationActivity
Implement all the NavigationActivity abstract methods
(in Android Studio if you click Alt + insert and select implement - methods all the function definitions are automatically generated).
public class NavigationTest extends NavigationActivity{
#Override
public Fragment firstFragment() {
//return the first fragment that will be shown
}
#Override
public Boolean showBackButtonInFirstFragment() {
//show back button already in the first Fragment
//set to True if this activity is called by another Activity
//the back button will then pop back to the previous Activity
}
#Override
public Boolean showMasterDetailLayoutInTablets() {
//set to false if you don't want a master-detail layout in tablets
}
}
Presenting a new Fragment
You can present a new fragment (with a nice animation) by calling the pushFragment method from NavigationActivity.
public void pushFragment(Fragment newFragment, animationType animation, boolean showAsDetailFragmentIfPossible)
newFragment (Fragment): New Fragment that will be presented
animation (animationType): Animation type enum: RIGHT_TO_LEFT, BOTTOM_TO_TOP, FLIP
showAsDetailFragmentIfPossible (boolean): If set as True, the user is in a Tablet, and you are using a master-detail layout, the Fragment will be shown in the detail Fragment (the panel in the right)!
Since you can access the activity from any Fragment with the getActivity() method, you can show a new Fragment from the currently displaying Fragment.
For example you can put this code within a button click listener:
NextFragment f = new NextFragment();
NavigationActivity nav =((NavigationActivity)getActivity());
nav.pushFragment(f,NavigationActivity.animationType.RIGHT_TO_LEFT,false);
You don't have to worry about implementing the back button behaviour. This is handled automatically by the NavigationActivity class.
There are thee basic types in Android to show UI in Android:
View
Fragment
Activity
Google IO 2018 introduced Navigation component which should make life easier. It is a wrapper under a standard mechanisms.
Here you can find NavGraph which looks like storyboard and NavController which help to navigate to destination