I have a button on Core game. I want when i click button, a Activity will run. I think i can use Interface but it do not work.
buttonPost.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
myGameCallback.startActivity();
}
});
Here is my interface
public interface MyGameCallback{
public void startActivity();
}
private MyGameCallback myGameCallback;
public void setMyGameCallback(MyGameCallback callback){
myGameCallback=callback;
}
And android code:
public class MainActivity extends AndroidApplication implements Main.MyGameCallback {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
Main main=new Main();
main.setMyGameCallback(this);
initialize(main, config);
}
#Override
public void startActivity() {
Intent intent = new Intent(this, Post.class);
startActivity(intent);
}
}
Please help me, thank you so much.
The Interface way to implement some native android functionality in LIBGDX works as follows.
First of all why your Main class implement screen? As far as I know the Main Class should implement Game. Screen is different then main class.
So here you go for Interface.
public interface MyGameCallback{
public void startActivity();
}
On AndroidLauncher
public class AndroidLauncher extends AndroidApplication implements
MyGameCallback{
// provide implementation of startActivity(); method.
}
Finally your main Game class should go like
public class MainGame extends Game {
public MyGameCallback myGameCallback;
public MainGame(MyGameCallback myGameCallback) {
super();
this.myGameCallback = myGameCallback; // initialize in constructor
}
Finally on the button in game where you want to start your activity do it like.
public class MainMenuScreen implements Screen {
private MainGame mygame;
public MainmenuScreen(MainGame game) { // initiaize maingame class so that you can call Interface method by its reference
this.mygame = game;
}
///////////////////////////////////
Finally on your button do call the method
buttonPost=new TextButton("Post",skin);
buttonPost.pad(20);
buttonPost.addListener(new EventListener() {
#Override
public boolean handle(Event event) {
mygame.myGameCallback.startActivity();
return true;
}
});
If You call it by just Interface name it wont work.
Related
I simplified my code for you to get better understanding it.
I have MyAdapter and MyActivity working both perfectly.
class MyAdapter extends RecyclerView... {
...
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
...
holder.mImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Listener) context).onSelected(object);
}
});
}
...
}
class MyActivity implements MyAdapter.Listener {
...
#Override
public void onSelected(Object object) {
// do things with object here
}
...
}
I want to make my another activity MyAnotherActivity implement MyAdapter.Listener.
When I run my app, and click on my object, an overriden onSelected() just ignored.
public class MyAnotherActivity implements MyAdapter.Listener {
...
#Override
public void onSelected(Object object) {
Log.e("MyAnotherActivity", "This text doesn't shows");
}
...
}
The used Listener implementation depends on the context parameter passed to MyAdapter constructor. Because on this line ((Listener) context).onSelected(object); you are casting the context field of the MyAdapter class to Listener implementation.
So when you are calling the constructor of the MyAdapter, you need to pass the context of MyAnotherActivity.
public class MyAnotherActivity implements MyAdapter.Listener {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
MyAdapter adapter = new MyAdapter(this /*Context of MyAnotherActivity*/, ...);
...
}
}
If you want to implement any methods inside of any class (not just activity) , you can use EventBus, a lightweight library for passing messages and events around.
It's very easy to implement and the code samples will help you out along the way
http://greenrobot.org/eventbus/
I am new to Android MVP Architecture. As far as I have researched the Presenter should be kept free from any android things like for example: Don't use getActivity or Context in the Presenters. I have written the following code where a BasePresenter is the parent class of all the Presenter classes that I will be using.The BaseView interface is the parent interface of all View classes and BaseActivity class is the parent class of all Activity classes. I have more than one activity and it is required to show Toast messages in all of my activity. So I have written the following code as follows. I am not very sure whether using the getactivity from the presenter class is a good practice or not. If it is not then can anyone suggest any better way to do it?
BasePresenter class
public class BasePresenter<V extends BaseView> {
private V mView;
private Context mContext;
public void attachView(V view) {
mView = view;
mContext=mView.getActivity();
}
public void showToast(String msg) {
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}
private Context getContext() {
return mContext;
}
public void detachView() {
mView = null;
}
}
BaseView class
public interface BaseView {
AppCompatActivity getActivity();
}
BaseActivity class
public class BaseActivity extends AppCompatActivity {
public AppCompatActivity getActivity() {
return this;
}
}
MainActivity class
public class MainActivity extends BaseActivity implements MainView {
MainPresenter basePresenter;
#Override
protected void onStart() {
super.onStart();
basePresenter = new MainPresenter();
basePresenter.attachView(this);
}
// some more codes here
switch (item.getItemId()) {
case R.id.about:
basePresenter.showToast("About is Clicked");
break;
case R.id.cart:
basePresenter.showToast("Cart is Clicked");
break;
case R.id.favs:
basePresenter.showToast("Favs is Clicked");
break;
case R.id.home:
basePresenter.showToast("Home is Clicked");
break;
}
}
It is not a good idea. You Presenter (base or otherwise) should not know about Context, Activity, Toast or anything else Android based.
View
displays things.
handles user input and passes it to the Presenter.
Presenter
decides what to do with user input.
gathers data from the model.
tells the View what to do.
So for your example of clicking Buttons and showing Toasts you would need a setup something like:
View Interface
This is how your Presenter will talk to your View. It will be implemented by the Activity.
public interface MainView {
void showToast(String message);
}
Presenter (Base & Main)
BasePresenter has almost no tasks at all. Simply there to bind the View interface. Note the method names in the MainPresenter are ambiguous to things like 'click' to seperate them from the View implementation.
public class BasePresenter<V> {
protected V view;
public void attachView(V view) {
this.view = view;
}
}
public class MainPresenter extends BasePresenter<MainView> {
public void about() {
view.showToast("About was clicked");
}
public void cart() {
view.showToast("Cart was clicked");
}
}
Activity
The Activity implements the View interface. It's responsible for passing user events to the Presenter and actioning the Presenter commands.
public class MainActivity extends AppCompatActivity implements MainView {
private MainPresenter presenter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MainPresenter();
presenter.attachView(this);
Button about = findViewById(R.id.button_about);
about.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
presenter.about();
}
});
Button cart = findViewById(R.id.button_cart);
cart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
presenter.cart();
}
});
}
#Override
public void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
In this setup the Presenter no longer knows anything about Android (has no imports from the framework at all) and you are able to write unit tests for it which can run directly on the JVM without Android dependencies.
Toast is actually visible on screen. So It should not be in presenter. It should be triggered from the View.
I'm trying to get a simple libgdx project running on Android. Everything is fine, but my InputProcessor does not fire its events.
I implemented everything according to this tutorial:
http://code.google.com/p/libgdx-users/wiki/IntegratingAndroidNativeUiElements3TierProjectSetup#Code_Example
The first call of "showToast" works fine and is shown on my screen => The showToast-Method does work. Unfortunately, I can't fire any of the InputProcessor events. Even the debugger does not stop there, so they are definitely not called.
Edit: Here is the complete code. I only omitted the Calculator Class, since it works fine and should not be of any conern here. If anyone disagrees with that I can always add it, of course.
Surface Class in libgdx main project (Main class so to say)
public class Surface implements ApplicationListener {
ActionResolver actionResolver;
SpriteBatch spriteBatch;
Texture texture;
Calculator calculator;
public Surface(ActionResolver actionResolver) {
this.actionResolver = actionResolver;
}
#Override
public void create() {
spriteBatch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("ship.png"));
calculator = new Calculator(texture);
actionResolver.showToast("Tap screen to open Activity");
Gdx.input.setInputProcessor(new InputProcessor() {
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
actionResolver.showToast("touchDown");
actionResolver.showMyList();
return true;
}
// overriding all other interface-methods the same way
});
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
calculator.update();
spriteBatch.begin();
calculator.draw(spriteBatch);
spriteBatch.end();
}
// Overriding resize, pause, resume, dispose without functionality
}
ActionResolver interface in libgdx main project
public interface ActionResolver {
public void showMyList();
public void showToast(String toastMessage);
}
Implementation of the ActionResolver interface within my Android project
public class ActionResolverImpl implements ActionResolver {
Handler uiThread;
Context appContext;
public ActionResolverImpl(Context appContext) {
uiThread = new Handler();
this.appContext = appContext;
}
#Override
public void showMyList() {
appContext.startActivity(new Intent(this.appContext, MyListActivity.class));
}
#Override
public void showToast(final String toastMessage) {
uiThread.post(new Runnable() {
#Override
public void run() {
Toast.makeText(appContext, toastMessage, Toast.LENGTH_SHORT).show();
}
});
}
}
Android Activity for inizializing the Suface-Class
public class AndroidActivity extends AndroidApplication {
ActionResolverImpl actionResolver;
#Override
public void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
actionResolver = new ActionResolverImpl(this);
initialize(new Surface(actionResolver), false);
}
}
I also implemented the InputProcessor in my Surface-class, but this should not (and did not) make any difference. Any ideas, what I'm missing?
I have an abstract class called BaseActivity (extends Activity) which has a function
public abstract void onLocationChanged();
All other activities extends this class. When I call BaseActivity's method onLocationChanged() I would expect, that all other classes that implement this method would call their onLocationChanged() method or at least the activity that is currently on top of the stack, but it seem that only one activity calls the method and it is not the one on top of the stack.
Can someone help?
here are relevant parts of my code:
abstract class BaseActivity extends FragmentActivity {
public static MyLocation location = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (location == null) {
location = new MyLocation(this);
}
}
public abstract void onLocationChanged();
}
public class MyLocation {
BaseActivity parrent;
public MyLocation(BaseActivity act) {
public MyLocation(BaseActivity act) {
this.parrent = act;
}
public void refreshMyLocation() {
/*location get refreshed here*/
this.parrent.onLocationChanged();
}
}
public class MainActivity extends BaseActivity {
#Override
public void onStart() {
BaseActivity.location.refreshMyLocation();
}
public void onLocationChanged() {
/*some stuff*/
}
}
You are calling on location changed on an instance of base activity not all of them at once. Without your code I don't know which one. But simply declaring a method in a base class does not mean it will be called on every class that implements it.
I dont understand why do you want to do that. I think you should need a Serivice that implements onLocationChanged and communicates with activities via Handler or BroadcastReceiver.
I have an activity which creates an object instance of my class:
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
...
Points myPoints new Points();
...
}
--------------------------------------------------------------
file Points.java:
private class Points {
...
HOW TO USE myView HERE ???
...
}
--------------------------------------------------------------
How do I use the UI objects in my class (which does not extend an
Activity)? Should I pass some context to my Points class? How do I do, exactly?
see you post, i've edited it , to fix the problem
hope it helps :=)
here is the Edit :
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView ;
protected void onCreate(android.os.Bundle savedInstanceState) {
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points(this);
myPoints.displayMsg("Hello World !!!");
}
}
--------------------------------------------------------------
file Points.java:
private class Points {
protected MyActivity context;
//add a constructor with the Context of your activity
public Points(MyActivity _context){
context = _context;
}
public void displayMsg( final String msg){
context.runOnUiThread(new Runnable() {
#Override
public void run() {
context.myView.setText(msg);
}
});
}
}
Your Points can't be a private class without being an inner class. So your code doesn't even compile...
Pass the view as parameter to the constructor of your Points class:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
Points myPoints new Points(myView);
private class Points {
public Points(TextView view) {
// todo
}
}
}
You should do everything and pass back the value to the activity to handle UI instead of doing any UI related stuff in the point stuff.
You can pass the main Activity's context (using Points(getApplicationContext());) to the class as a constructor parameter. You could also pass the specific UI elements you want to manipulate.
A better way to do it, however, may be to have Points not know about the Activity. Have your Activity call Points methods and take the necessary actions based on the method output.
You could just pass the view to your class.
Points myPoints = new Points(myView);
private class Points
{
private TextView mTextView;
Points(TextView textView)
{
this.mTextView = textView;
}
}
i was in same trouble..
i found the simple way..
make a static variable and function ...
call from other class..
TestActivity.java
public class TestActivity extends Activity {
static EditText edit_text1;
public void onCreate(Bundle savedInstanceState)
{
.....
edit_text1 = (EditText) findViewById(R.id.edit_text1);
.....
}
public static void setMSG(String str)
{
edit_text1.setText(str);
}
}
Test2.java
TestActivity.setMSG("this is text");
Could work using an interface
file MyActivity.java:
public class MyActivity extends Activity implements Points.MyListener {
TextView myView;
... onCreate(...){
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points();
//pass in MyActivity's instance of the listener
myPoints.addListener(this);
}
#Override
public void updateTextView(String message){
myView.setMessage(message);
}
}
file Points.java:
public class Points {
public Points(){
}
public interface MyListener{
void updateTextView(String message);
}
MyListener myListener;
public void addListener(MyListener listener){
myListener = listener;
}
public void updatePoints(){
//do some operations in calculatePoints()
String points = calculatePoints();
//update views using MyActivity's implementation of updateTextView()
myListener.updateTextView(points);
}
}
Doing it this way, events can be fired / messages sent, for lack of better terms, from the external class to update the Activity UI. This might be overkill if all sb need is to call a method in the Points class that returns something