First of all, I'm well aware that this error is occur because I'm trying to call window/dialog through a Context that is not an Activity.
But isn't there any solution to that. My requirements are; I have a Dialog with a custom style sheet in a method of a normal JAVA class. I want to call that method from any Activity class when I need to load the Dialog.
In my Activity class I'm having following code set;
HomeClass homeClass = new HomeClass();
homeClass.showSplashScreen();
Then in my HomeClass I have following code set;
public void showSplashScreen() {
splashDialog = new Dialog(HomeActivity.getAppContext(), R.style.SplashScreen);
splashDialog.setContentView(R.layout.splash_screen);
splashDialog.setCancelable(false);
splashDialog.show();
}
By maintaining this design, is there any way to get rid of the WindowManager$BadTokenException
Thank You
I am going to modify your code, that maybe helpful for you...
HomeClass homeClass = new HomeClass(this);
homeClass.showSplashScreen();
In Your Home class.. add parametric constructor..
public class Home {
private Context context;
public Home(Context context){
this.context = context;
}
public void showSplashScreen() {
splashDialog = new Dialog(context, R.style.SplashScreen);
splashDialog.setContentView(R.layout.splash_screen);
splashDialog.setCancelable(false);
splashDialog.show();
}
Pass Your Activity to showSplashScreen() Method...
Do like this..
HomeClass homeClass = new HomeClass();
homeClass.showSplashScreen(Your Actvity);
In Your Home class
public void showSplashScreen(Activity curActivity) {
splashDialog = new Dialog(curActivity, R.style.SplashScreen);
splashDialog.setContentView(R.layout.splash_screen);
splashDialog.setCancelable(false);
splashDialog.show();
}
Related
I have following code in which I want to pass the context as a first parameter but I cant , tried all possible answers from net such as : getActivity(), getContext(), this , getActivity().getApplicationContext()
Nothing works and my app crashes because of exception :| My Class is extended from fragment
public void onClick(View v) {
HashMap postData = new HashMap();
PostResponseAsyncTask task = new PostResponseAsyncTask(this,postData);
task.execute("http://ashna.netau.net/A_location.php");
}
Your function onClick() is probably inside an object implementing the interface View.OnClickListener which contains no functions like getActivity() or getContext().
Try the following:
final Context context = getActivity();
View.OnCLickListner mListener = new View.OnClickListener() {
public void onClick(View v) {
HashMap postData = new HashMap();
PostResponseAsyncTask task = new PostResponseAsyncTask(context,postData);
task.execute("http://ashna.netau.net/A_location.php");
}
}
you can create application class and create a global instance of the application variable inside in it. So you can have the access to the application context from anywhere in the app.
Try this:
PostResponseAsyncTask task = new PostResponseAsyncTask(v.getContext(),postData);
I have a single popupWindows that works well when I call it in the activity. But my idea is to set specific class for this popupWindows and call it by different activities. How is-it possible ?
My popupWindows class
public class GestionCat extends PopupWindow
{
Context m_context;
public GestionCat(Context context)
{
super(context);
m_context = context;
setContentView(LayoutInflater.from(context).
inflate(R.layout.cat, null));
setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
}
public void show(View anchor)
{
showAtLocation(anchor, Gravity.CENTER, 0, 0);
}
}
And how I call it :
Activity activity = this.getParent();
View view = activity.findViewById(R.layout.main_layout);
Context context = getApplicationContext();
GestionCat gestionCat = new GestionCat(context );
gestionCat.show(view);
thank for help
What you are looking for is the creation of a singleton. In your GestionCat class you want the following code:
private GestionCat _gestionCat;
public static GestionCat getInstance()
{
if(_gestionCat == null)
{
_gestionCat = new GestionCat();
}
return _gestionCat;
}
Now you can use GestionCat.getInstance() every time to get the same instance of the GestionCat that you are looking for. That way you can share the popup window in multiple classes.
See http://msdn.microsoft.com/en-us/library/ff650316.aspx for more information.
I'm using android annotations, I'm trying to annotate this class so that I can save a value into my shared preferences (annotated) class using #pref. I've managed to find a work around with an intent and a broadcast receiver however this is not ideal and now that I want to fetch a value from the shared preferences in this class to show as the default item selected in the spinner it's starting to leave a smell on my code.
Is there any way to annotate this class?
public class SelectNewsFeedDialog extends Dialog {
private Context context;
private Button confirmButton;
private Spinner spinnerTeams;
public SelectNewsFeedDialog(final Context context, ArrayList<Team> listTeams) {
super(context,R.style.cust_dialog);
this.context = context;
setContentView(R.layout.dialog_choose_news_feed);
spinnerTeams = (Spinner) findViewById(R.id.dialog_news_feed_spinner_teams);
confirmButton = (Button) findViewById(R.id.dialog_news_feed_button_confirm);
confirmButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Team team = (Team)spinnerTeams.getSelectedItem();
Intent intent = new Intent(context, IntentCenter_.class);
intent.putExtra(context.getString(R.string.extra_update_team_news_feed), team.url.toString());
intent.setAction(context.getString(R.string.action_update_team_news_feed));
context.sendBroadcast(intent);
dismiss();
}
});
SpinnerTeamsAdapter adapter = new SpinnerTeamsAdapter(context, listTeams);
spinnerTeams.setAdapter(adapter);
}
}
Currently, we haven't any annotation for Dialog classes. You may want to uses #EBean on this but the compiler is yelling on missing constructors.
The solution is to uses a DialogFragment instead of a Dialog and annotate this class with #EFragment. The following code should works :
#EFragment(R.layout.dialog_choose_news_feed)
public class SelectNewsFeedDialog extends DialogFragment {
#ViewById
Button confirmButton;
#ViewById
Spinner spinnerTeams;
#Extra
List<Team> listTeams;
#Click
public void confirmButtonClicked() {
Team team = (Team) spinnerTeams.getSelectedItem();
Intent intent = new Intent(context, IntentCenter_.class);
intent.putExtra(context.getString(R.string.extra_update_team_news_feed), team.url.toString());
intent.setAction(context.getString(R.string.action_update_team_news_feed));
context.sendBroadcast(intent);
dismiss();
}
#AfterViews
public void init() {
SpinnerTeamsAdapter adapter = new SpinnerTeamsAdapter(getActivity(), listTeams);
spinnerTeams.setAdapter(adapter);
}
}
However, using #Extra on a list is not a good idea. You should :
* use a list of ids annotated with #Extra
* or, uses a setter and passes this list to your adapter after the dialog was been initialized.
Hope this helps
First, I am an android rookie, so my solution ways can be found awkward, and i am open to suggestions.
I am trying to create a game manager object that handles all transitions between activities. And my purpose is that while in an activity, menuOut method will call the changeActivity method of GameManager object with nextActivity argument and changeActivity will start that Activity. I am getting errors consistently, and did not find a solution.
Here is my source codes:
GameManager:
public class GameManager{
public SplashScreen splash = new SplashScreen();
public MainScreen main = new MainScreen();
public LoadingScreen load = new LoadingScreen();
Context tempContext;
public GameManager(Context base) {
super();
tempContext = base;
}
public void start(){
createScreens();
Intent intent = new Intent(tempContext, splash.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent);
}
public void createScreens() {
//here is the method that i am trying to find a solution
((SplashScreen)splash.getContext()).setGameClass(this);
((MainScreen)main.getContext()).setGameClass(this);
((LoadingScreen)load.getContext()).setGameClass(this);
}
public void changeMenu(MenuType nextMenu, MenuType previousMenu){
Intent intent2;
switch(nextMenu){
case MAIN_SC:
tempContext = main.getContext();
intent2.setClass(tempContext, main.getClass());
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent2);
case GAME_LOADING_SC:
tempContext = load.getContext();
intent2.setClass(tempContext, load.getClass());
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent2);
default:
break;
}
}
}
And here is SplashScreen activity:
public class SplashScreen extends Activity {
public Context context = this;
public GameManager gameman;
private static final int SPLASH_DURATION = 4000;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
splash();
menuOut();
}
public Context getContext() {
return this;
}
public void splash() {
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setBackgroundResource(R.drawable.game_loop_splash);
setContentView(ll);
Handler handler = new Handler();
// run a thread after 2 seconds to start the home screen
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
}, SPLASH_DURATION);
}
public void setGameClass(GameManager game){
gameman = game;
}
private void menuOut(){
gameman.changeMenu(MenuType.GAME_LOADING_SC, MenuType.GAME_SPLASH_SC);
this.onDestroy();
}
}
I can not return to the GameManager and call the changeMenu method.
I am very exhausted to get null pointer exceptions.
Any idea?
From what I read, you are trying to implement a singleton pattern. There are two ways I'd recommend to do that on android:
Extend the Application class, register your class in the manifest and use getApplication() in your activities to get access to it:
// In MyApplicationSubclass.java:
public final class MyApplicationSubclass extends Application {
/* ... */
public void myMethod() {
// insert some code here
}
/* ... */
}
// From your Activity:
((MyApplicationSubclass) this.getApplication()).myMethod();
Use a "normal" java singleton pattern, e.g. use a private constructor and keep one static instance within your GameManager class (this is the way the Android docs recommend, but I personally prefer the first way when having something that is logically bound to the Application).
Also, if you're only using your central class to do static stuff, you can just mark all its method as static and access them directly. Transfer Context objects as parameters to these methods, and you should be able to start activities without any static variables (which are sometimes hard to implement properly in Android, as your VM might get restarted from time to time).
I stuck at this issue many times and I passed the problem in different ways and I'm not sure that I made it in the right way.
I simplified the problem in a the following example. I know that I can pass only the data to the class but I do want to pass the editText cause I have this problem with more difficult UI controls.
mainactivity.java
public class mainactivity extends Activity {
public EditText clickEditText;
int count =0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
newTxt();
}
public void newTxt() {
txt = new MyText(context);
txt.updateTextEdit("Main Activity");
}
}
myText.java
public class MyText
{
private Context _context;
// constructor
public MyText(Context context)
{
_context = context;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)findViewById(_context.R.id.editTextClick); // ????
strEditText.setText(str + " and myTxt");
}
}
if you could explain me how to fix the updateTextEdit function. i passed the context of the main activity. How can I change the editText? Thank you very much!!!
If you really want to do this this way, you need to save a reference to Activity, not Context. Like this:
public class MyText
{
private Activity _activity;
// constructor
public MyText(Activity activity)
{
_activity= activity;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)activity.findViewById(R.id.editTextClick);
strEditText.setText(str + " and myTxt");
}
}
and in newTxt() you will need to change:
txt = new MyText(context);
to:
txt = new MyText(this);
But wouldn't it be easier to just put this method inside your activity? Why do you want it in another class? If it really needs to be in another class, you could make that class an inner class of your activity and you would still have access to the activity's methods and member variables.
There's a similar question here
How to access Activity UI from my class?
You didn't say how you obtained the context, you should use this and get the mainactivity in the other class. not context.
then you can call runOnUIThread to perform UI updates.