Android: Updating textviews in multiple activities - java

I need some pointers on doing the following:
lets say i have 10/20 (number doesn't matter) of activities.
each of these activities has a textview that should work like a counter.
each of these activities has a button to go to the next activity.
this counter starts when the app is launched, and increment itself every second.
So what i did so far is:
have in my main activity a method that instantiate a class that extends Thread.
In that class in the run() method, i increment a variable when a second passes.
Now i'm stuck on what i should do next. Any pointers would be appreciated thanks.
Edit: i need a way to communicate from inside the run method, to whichever activity is now currently on screen, to update its textview.

Just a bit of theory here for standard Object Oriented Programming : stick to the recommended principles like Loose Coupling which makes your project code less tied to each other. You can read more on that later.
Now, using Events, you can setup a system that is synonymous with the natural Publisher/Subscriber design pattern. Like this:
The activity that needs to notify the other activities is called Publisher and the other activities that need to be notified are called Subscribers.
From here:
There are already built and tested libraries to do Events in android. Like my favorite EventBus.
Step 1 Add this line to your app-level build.gradle file:
compile 'org.greenrobot:eventbus:3.0.0'
Then create a simple Plain Old Java Object aka POJO class like this:
public class UpdateTextViewEvent{
private String textToShow;
public UpdateTextViewEvent(String text){
this.textToShow = text;
}
//add your public getters and setters here
}
Step 2 Notify others:
When you want to notify anyone of the changes, you simply called this method:
EventBus.getDefault().post(new UpdateTextViewEvent("Some new Text"));
Step 3 Receive notifications
For those who want to be notified of this event, simply do this:
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
NOTE: to actually handle the event:
#Subscribe
public void onEvent(UpdateTextViewEvent event){
String text = event.getTextToShow();
//now you can show by setting accordingly on the TextView;
}
This is so much easier to do, do decouple your code by eliminating static references in your different activities
I hope this helps! Good luck!

make that Textview in second class as
public static Textview text;
and call it in main activity as
SecondActivity obj=new SecondActivity();
obj.text.settext("");

You can create one another activity e.g. BaseActivity extend with Activity class and your all 10/20 activity extends with created BaseActivity Class.
You can use your textview with protected access specifiers.

What you need to do is inside the counter class, create an a method and passed in a TextView as the parameter. Then create an int variable and set the counter as the instance:
Like this
public static class Counter extends Thread{
private static int x;
#Override
public void run(){
x = counter;
}
public void setCounter(TextView tv){
tv.setText(String.valueOf(x));
}
}
Now call this method setCounter(TextView) in all the activity's onCreate() method you'll like to display the counter, and passed in your the layout TextView as the argument. Like this
...
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState):
....
TextView cTextView = (TextView)findViewById(R.id.texT1);
Counter c = new Counter();
c.setCounter(cTextView);
}

Related

Is there an alternative in Android Java for Message sendToTarget to access View in inner class of an activity?

i have an activity where i have a text view. I am also using an sdk which has some events.
Within on of these events i need to display some data at the TextView.
The events are in an external class and i got them via some interfaces.
The interfaces iam implementing within the Activity.
I am using Handler and Message to set the text into the TextView within the implementation of the interface.
I would like to know if there is another way to set the text within the the interfaces except Handler and Message.
Here is that code:
public class MyActivity extends AppCompatActivity {
private TextView nameTextView;
// some code
// implementing interfaces of external class
Service.ServiceEvents events = new Service.ServiceEvents() {
#Override
public void onSomeEvent(String name) {
nameTextView.setText(name); // not working
Message m = myHandler.obtainMessage(0, nameTextView);
m.sendToTarget();
}
Handler myHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message message) {
String s = message.obj.toString();
nameTextView.setText(s);
}
};
}
} // end of activity
Is there another way to set the text in the TextView?
Please Help.
What to use
You can do it by using an interface.
How to implement
Create a new interface and give it a name whatever u like.(Here it is SampleInterface).
Add some void methods to like this
void onSomeEvent(String name);
Create a object of it in the class where you get the data from the sdk and add this listener in its constructor. Something like this
public YourJavaClassName(SampleInterface sampleInterface) {
this.sampleInterface= sampleInterface;
}
When you receive an update in the sdk, you can call it like this
void onDataReceived(String name){// I don't know how you get the value from the sdk so I wrote this
sampleInterface.onSomeEvent(name);
}
You are done with implementing it in the sdk receiver class. Now you need to add to the main activity to receive and update data.
Create the object of the class where you receive the data from the sdk.Like this
MySDKReceiverClass mysdkreceiverclass;
mysdkreceiverclass = new MySDKReceiverClass(this);
Implement the interface in the activity and there you ge the values and you can set it in the textview.
Note: You need not add any runnable or handler or anything.Whenever there is a value change, the listener is called and the value is set.

Java / Android - How can I know that a variable from any instance of a class is true?

This question is not manly for Android, but I will use an android example to explain.
I want to create a class that should override the method onTouchListener, to be used on any object that uses those touch methods.
Since after a touch input, the method starts a function, and since it's a class, it can be instantiate several times (and I want to be instantiate several times), I want to prevent that two instances are called at the same time.
I guess I could create a variable inside the class, that assured that if it's true, it can run the method, but I need to check it for all of the class instances.
And since I want to make this a library, I need to do this inside the class itself.
So my question is,
(Java Question) How can I know that a variable from any instance of a class is true?
(Android Question) Or if this is not possible, How can I prevent multiple touch events at the same time?
You could achieve that with static data and/or method for this class. A static element can be accessible from anywhere using the class name:
ex: MyClass.isAlreadyRunning();
you could for example store in an array all the running status of the instances, and create a static method that checks the array if one is already running.
You can think about making a Singleton Class. Wiki Link
Singleton classes allows to create ONLY one instance/object of that class and then reuse it.
You can use a static field in this context. A static field is identicaly for all instances of an class.
You can do it maybe like this:
public Example implements TouchInterface{
private static boolean actuallyRunning = false;
public void touchExecute(){
if(!actuallyRunning){
actuallyRunning = true;
callYourFunction();
actuallyRunning = false;
}
}
}
You can use singleton class if you want one one instance and if you want to handle the multiple touch events
you can disable as soon as your handler start and enable after that.
you can add a time span in normal practice it is one sec but it depends on you handler's complexity
Like this example:
// Make ur activity class to implement View.OnClickListener
public class MenuPricipalScreen extends Activity implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
// setup listeners.
findViewById(R.id.imageView2).setOnClickListener(MenuPricipalScreen.this);
findViewById(R.id.imageView3).setOnClickListener(MenuPricipalScreen.this);
....
}
.
.
.
// variable to track event time
private long mLastClickTime = 0;
//View.OnClickListener.onClick method defination
#Override
public void onClick(View v) {
// Preventing multiple clicks, using threshold of 1 second
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
return;
}
mLastClickTime = SystemClock.elapsedRealtime();
// Handle button clicks
if (v == R.id.imageView2) {
// Do ur stuff.
}
else if (v == R.id.imageView2) {
// Do ur stuff.
}
...
}
.
.`.
You should put "public synchronized" void, so it will prevent to be called in parallel. If you must override, then put a synchronized object in the method so it will do the same.

How to reduce size of MainActivity/outsource UI code

most of my apps are apps with just one screen (due to the functionality) sometimes being extended by "floating" popups that are basically RelativeLayouts (containing other UI elements) that are being added to the Main layout, keeping the UI Elements of the Main layout active and "touchable" in the background.
For a better understanding, please just look at the sketch (purely symbolic):
If you include all the stuff from the popups as well, I have about 90 UI elements, a dozen of custom View classes like buttons, sliders, ... at a time, all of them needing to have certain listeners running on them, all of them having to be resized on start up [...]
I, in fact, write quite efficient (in terms of amount of bytes used) code, and if there is a 3-line method to return a value that replaces 4 lines of additional code, I write this method just to satisfy myself. However, I quite don't understand how to outsource code from my MainActivity to other classes. Of course, if there is a calculation to be made, this is something that I put into another class rather than just creating a method in my MainActivity class. Anyway, my MainActivity is now at 1600 lines of code which is an awful amount of text to overview for debugging, adding or changing code. The variable declarations of my UI elements alone take 100 lines of code (maybe 70 lines if compressed)
That was the longest explanation I ever made for a post but now we get to my question:
How can/do you outsource code like listeners, UI stuff like findViewById() or similar things to other classes? Are there common practices to do so in an efficient way? I don't want to go for clumsy workarounds that skyrocket the CPU, so "smooth" stuff is stuff I am looking for.
It might be KIND OF off-topic but I hope it's ok to be asked here.
I'm not sure that there is particular answer on your question because I suppose it's all about experience which you can get reading source code of other projects for instance. But I have few advices which could help you:
1. Use libraries which eliminate boilerplate code like findViewById and listeners. One of them is Butterknife
7 lines of code:
View text = findViewById(R.id.text_id);
text.setOnClickListener(
new View.OnClickListener() {
#Override public void onClick(View v) {
//
}
}
);
2 lines code:
#OnClick(R.id.text_id) public void handleClickOnText() {
//
}
2. Use static helper classes:
4 lines of code:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.new_message);
builder.setTitle(R.string.create_calendar_title);
builder.show();
1 line of code:
DialogsHelper.newMessage(this);
3. Read about MVP. It's about modular app architecture. Roughly speaking it helps to divide raw View from logic.
Basic sample:
public static class SomePresenter {
private SomeView view;
public SomePresenter(SomeView view) {
this.view = view;
view.showProgressLoading();
loadData();
}
private void loadData(){
//loading data from some server
}
private void loadingDataHandler(SomeModel model){
view.showData(model);
}
}
public static class SomeView extends View{
#Inject(R.id.text_progress_title) TextView text;
public SomeView(Context context) {
super(context);
ButterKnife.inject(this);
}
public void showData(SomeModel model){
text.setText(model.dataA + ":" + model.dataB);
}
public void showProgressLoading(){
text.setText(R.string.progress);
}
}
public static class SomeModel{
public final int dataA;
public final int dataB;
}
And your onCreate method of activity could look like this:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
new SomePresenter(someView);
}

Android message between classes

This is my first post and I did not find anything similar, so I've decided to ask.
Im developing a Poker Game for Android to practice the SDK and refresh/improve my Java. Its a simple app that control a texas hold'em poker hand.
Initally, I wrote my classes using only Java SE and it looks fine. Each class has its own purpose and testing it with console input/output, I can see it really works :)
Last week, I decided to port it to Android to see things happening through a graphic interface, so I got the resource images, make an Activity and included my poker package.
Before port to Android I can just put a println (or readLine) to see whats going on and send my inputs. Now Im stuck in how each class can communicate to the game activity to provide what must be drawn. If possible, I don't want insert Android draw code inside game classes. Im trying find a way to exchange messages between my Activity and the game classes and Id like some suggetions. Im new in developing Android apps, so I dont know all mechanics to do this.
Below are the snippet from my activity:
package my.poker.game;
//import stuff
public class ActivityHand extends Activity
{
private static Vector<Player> Players = new Vector<Player>();
public static final int MAX_PLAYERS = 8;
public static void startEmptyTable()
{
Players.removeAllElements();
Players.setSize(MAX_PLAYERS);
}
public static void LeaveTable(int pos)
{
Players.set(pos, null);
}
public static void SitTable(int pos, Player player)
{
Players.set(pos, player);
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int cash = 1000;
startEmptyTable();
SitTable(0, new Jogador("William", cash));
SitTable(2, new Jogador("Richard", cash));
SitTable(4, new Jogador("John", cash));
SitTable(6, new Jogador("Paul", cash));
SitTable(8, new Jogador("Albert", cash));
//Start a Hand.... in future this will be a loop for each Hand
Hand hand = new Hand(Players);
}
}
The object hand, will select a Dealer, deal the cards, control the small and big blinds and start the game loop.
The question is: how the hand class can tell the Activity to Draw and pass an object containing what to draw?
Thanks a lot for your help
Editing: I've decided to try implementing it using a Handler and passing simple messages. As I read from Handler at Developers a Handler object is assigned to thread's MessageQueue, so I tried to put this into my Activity Class (before Hand hand = new Hand (...) ):
Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
Bundle bundle = msg.getData();
// Do something with message contents
}
};
And inside the Hand class I put this when I want to draw something:
Handler handler = new Handler();
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("Key", "The Key's Value");
msg.setData(bundle);
handler.sendMessage(msg);
As I understood, both handlers are from same thread, so they are assigned to same MessageQueue right? I tought when I send a message inside Hand class, the Activity class can receive it in handleMessage method and processes any message I send, but handleMessage doesn't execute.
What am I missing?
Thanks again
To call methods in the activity, you want to pass the activity to this class.
for example:
public class PokerActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
Hand hand = new Hand(this);
}
public void setVisibleHand(Player player)
{
<do something in the activity>
}
}
public class Hand
{
PokerActivity pokerActivity;
public Hand(PokerActivity activity)
{
this.pokerActivity = activity;
}
public void setVisibleHand()
{
pokerActivity.setVisibleHand(player1);
}
}
Now, this might not be the best way to do it. In Android you have to be carefull to not leak the context, or you might be getting trouble with the memory. (simply passing the activity/context might be the easy way, but is also the easiest way to leak the context.)
I'd advise you to look at some simple tutorials first, to get a feeling of how android activities work.
You could use a Handler and Message system to communicate between your classes.
This tutorial by Lars Vogel should help you Android Threads, Handlers and AsyncTask - Tutorial
You will have to create another class to make the interactions with your own classes and the activity itself.
From that class you can use the activity context to control the android activity.
The approach about using Handlers and Messages is good but would require you to modify your game classes.
Maybe you should extend View Class to draw the Hand.
http://developer.android.com/reference/android/view/View.html

setOnClickListener to all extended ImageViews - Java

I have a custom class that I've written that extends ImageView (for Android Java). I want to add a ClickListener to every instance I create of the class that will do the same thing (just animate the ImageView.
I tried a few different things to no avail. The code below is what I want to accomplish but it's being applied to an instantiated object of the class.
MyCustomImageView fd = new MyCustomImageView(this);
fd.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Animater(fd);
}
});
I tried using "implements onClickListener" on the class declaration and then a public void onClick() method in the class, and that didn't work for me.
I also tried using the code snippet above with a "this" instead of "fd" and that didn't work either.
I'm relatively new to java and this is out of the scope of my knowledge. Any assistance you can provide is greatly appreciated.
It's really easy. You have to do it in your custom class:
public class MyCustomImageView extends ImageView{
public MyCustomImageView(Context context){
super(context);
setOnClickListener(theCommonListener);
}
private OnClickListener theCommonListener = new OnClickListener(){
public void onClick(View v) {
// do what you want here
}
}
}
There are other ways to do it, but this is one is really easy to implement and understand. Every instance of MyCustomImageView will have the same event listener (unless you override it from outside).

Categories