How to update a TextView of an activity from another class

匿名 (未验证) 提交于 2019-12-03 02:00:02

问题:

Iam new to android/java programming. I have two class, one is an activity and other normal class. In my activity class contains TextView. Can i update TextView of activity class from normal class. I tried with random code, but it fails. Please provide a solution...

// activity class public class MainMenu extends Activity {     public TextView txtView;  @Override public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);         TextView txtView = (TextView)findViewById(R.id.text);     }      }  // other class public class ClassB {    public ClassB(){    }     public void Update(){         TextView txtView = (TextView)findViewById(R.id.text);         txtView.setText("Hello");    } } 

回答1:

You have to pass the Context reference via constructor.

public class ClassB {    Context context;    public ClassB(Context context){      this.context=context;    }     public void Update(){         TextView txtView = (TextView) ((Activity)context).findViewById(R.id.text);         txtView.setText("Hello");    } 


回答2:

The preceding two examples requires TextView to used directly within the other class. However, there are cases where TextView shouldn't be present in the other class. e.g. your class B is use to update various Activities, where some activity updated on TextView, others might be on EditText.

Hence the below solution guide you on how you could decouple your TextView from other class, yet you could still achieve what you want. It's using the Interface approach.

Firstly, declare an interface where you could have class B to communicate to Activity, calling it MyCallBack

public interface MyCallBack  {     // Declaration of the template function for the interface     public void UpdateMyText(String mystr); } 

Next in your Activity, implements MyCallBack, and hence it's function definition. In this function, you will be receiving the String from Class B, that you could do whatever you like e.g. update the TextView (or EditText etc...)

public Class MyActivity extends activity implements MyCallBack; {     // ... whatever code of your activity      @Overrid     public void UpdateMyText(String mystr)     {         TextView txtView = (TextView)findViewById(R.id.text);         txtView.setText(mystr);     } } 

Lastly, then you could declare ClassB that takes in MyCallBack (i.e. your Activity class object that is also a MyCallBack). From there you could use ClassB to communicate back to Activity and get it update it's TextView through the UpdateMyText function

public class ClassB {     MyCallBack mCallBack = null;     public ClassB(MyCallBack callBack){             this.mCallBack=callBack;     }       public void dosomething(){         // Do something to get String         String myString = str;         this.mCallBack.UpdateMyText(str); } 

Hope this helps better architected structure of decoupling the Activity property from ClassB.



回答3:

You can make a getter method in your Activity.

In your Activity class:

public TextView getTextView() {  TextView txtView = (TextView)findViewById(R.id.text); return txtView; } 

In your ClassB class:

public void Update() {           MainMenu obj = new MainMenu();           TextView tv = obj.getTextView();           tv.setText("hello");  } 


回答4:

This is actually a deceptively "simple" question, but in reality a complicated problem in the context of Android development.

Activities are the "process entry point", meaning that any Activity you see can act as the "first point of entry to your application on start-up". People think that only the Activity that has the MAIN/LAUNCHER intent filter can be launched at start-up, but this is false.

Any Activity can act as the "first Activity", because Android can restart it from any point with the current active navigation stack.

Anyways, with that in mind, an Activity can show a View, and people often use the Activity to hold each screen of their app (instead of using it as an entry point, and swapping out view controllers in it ~ fragments).

So if you have multiple Activities, then you need to share data between them in such a way, that you take it into consideration that both activities can be started up at any time as the first Activity of the app.


For this, what you need to do is not "set the text view's text directly from another class", but you need to modify observable shared data.

The newly released official Android Architecture Components provide the LiveData class, which has a subclass called MutableLiveData.

To update the data from one class to another Activity, what you must do is have a global data exposed as a LiveData

public class MyApplication extends Application {     private static MyApplication INSTANCE;      DataRepository dataRepository; // this is YOUR class      @Override     public void onCreate() {         super.onCreate();         INSTANCE = this;         dataRepository = new DataRepository();     }      public static MyApplication get() {         return INSTANCE;     } } 

The DataRepository should expose LiveData:

public class DataRepository {     private final MutableLiveData data = new MutableLiveData();      public LiveData getMyData() {         return data;     }      public void updateText(String text) {         MyData newData = data.getValue()                              .toBuilder() // immutable new copy                              .setText(text)                              .build();         data.setValue(newData);     } } 

Where the Activity subscribes to this:

public class MyActivity extends AppCompatActivity {     DataRepository dataRepository;      TextView textView;      @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         MyApplication app = (MyApplication)getApplicationContext();         dataRepository = app.getDataRepository();          setContentView(R.layout.main_activity);         textView = findViewById(R.id.textview);          dataRepository.getMyData().observe(this, new Observer() {             @Override             public void onChange(MyObject myObject) {                 textView.setText(myObject.getText());             }         }     } 

So to update this text, you need to get the DataRepository class, and call updateText on it:

DataRepository dataRepository = MyApplication.get().dataRepository(); dataRepository.updateText("my new text"); 

And this will properly update your Activity text view.



回答5:

you can do the following thing. I tried it and it worked. Just pass in the reference to the TextView while calling the method from another class. The problem in your version, is that there is conflict between TextView because you are declaring it twice. Instead declare it only once and pass it as an argument while calling the method in another class. Cheers!!

    // activity class   public class MainMenu extends Activity {     public TextView txtView;  @Override public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);         TextView txtView = (TextView)findViewById(R.id.text);         ClassB.update(txtView);     }      }      // other class        public class ClassB {        public ClassB(){        }         public void update(TextView tv){             tv.setText("Hello");        }     } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!