can access a radio buttons checked state from anothe class in android - java

I have a 'MainActivity class', inside that i have the object of radio button. i have an another class 'classB' inside the 'MainActivity' how can i able to access radio buttons checked state "RB1.isChecked()" from classB?
public class MainActivity extends Activity
{
public RadioButton RB1
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
RB1 = (RadioButton)findViewById(R.id.radioButtonA);
}
public class classB extends BroadcastReceiver
{
}
}

Make radio button static so you can access it in any other class.
public static RadioButton RB1;
In classB access Radiobutton using MainActivity.RB1

The rb1 object is accessible with in your nested class so use it like this:
rb1.isChecked()
public class classB extends BroadcastReceiver
{
void doSomething(){
if(rb1.isChecked()){
//place your code here
}
}
class B is an Non Static Inner class so it can access members of its enclosing class without any change:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Both the above answers are correct even if you need to use the Class B else where you can use the sharedpreferences like this
SharedPreferences prefs1 = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
save the state of the radiobutton inside onCheckedChangeListener
onCheckedChange(boolean ischecked)
{
SharedPreferences.Editor editor = prefs1.edit();
editor.putBoolean("confirm", isChecked);
editor.commit();
}
and then you can access this anywhere
boolean rbcheckedState=prefs1.getBoolean("confirm",true);

Related

There are 3 activities A, B and C, Update a text in A from C

So There are 3 activities A, B and C.
From Activity A, I go to activity B in activity B, I perform some tasks and I go to Activity C from Activity B.
I activity C, I have a button and some data, when I click the button I should update text in activity A. Is there a best way to do it?
edit: I do not want to go to back, when I click the button in activity C, but the text present in the activity a should be updated, later when I reach the activity a I should see the changes.
I think, you should create a separate class that you will share between your activities A, B and C. The class should has a field, which will store text for your TextView in activity A. And there is a good variant to use Observer pattern (rxJava or custom decision).
Example:
SharedStateModel is used to save state for ActivityA.
That decision is not very clear, because it breaks dependency inversion rule so I recommend you to use Dagger 2 to inject SharedStateModel into ActivityA and ActivityC and manage its component's lifecycle like I describe in comments to SharedStateModeClass.
/*
Let's make that state-class a local singleton - you create it in onCreate of ActivityA and
further it can be destroyed in onDestroy of ActivityA.
*/
public class SharedStateModel {
private PublishSubject<String> stateListener = PublishSubject.create();
private String viewState;
private static SharedStateModel instance;
private SharedStateModel() {
}
public void setViewState(String viewState) {
this.viewState = viewState;
stateListener.onNext(viewState);
}
public PublishSubject<String> getStateListener() {
return stateListener;
}
public void destroyViewState() {
instance = null;
}
public static SharedStateModel getInstance() {
if (instance != null) {
return instance;
} else {
instance = new SharedStateModel();
return instance;
}
}
}
public class ActivityA extends AppCompatActivity {
#BindView(R.id.textView)
private TextView textView;
private SharedStateModel sharedStateModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
sharedStateModel = SharedStateModel.getInstance();
sharedStateModel.getStateListener().subscribe(
textViewState -> textView.setText(textViewState));
}
#Override
protected void onDestroy() {
super.onDestroy();
sharedStateModel.destroyViewState();
}
}
public class ActivityC extends AppCompatActivity {
#BindView(R.id.button)
private Button button;
/*
Let's assume that you want to send a message from EditText in ActivityC
*/
#BindView(R.id.editText)
private EditText editText;
private SharedStateModel sharedStateModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
sharedStateModel = SharedStateModel.getInstance();
button.setOnClickListener(view -> sharedStateModel.setViewState(
String.valueOf(editText.getText().toString())));
}
}
And I want to recommend you good guides from Eugene Matsyuk if you want to learn Dagger 2.
2 way
when you leaving activity C and going to activity A, pass the value from activity C to A just like you are going to a new activity. then set the text view.
Pass your textView object from activity A activity B, then activity B to activity C. in activity C just setText normally with the textview object you bring from activity A to activity C.

Can't reference class buttons from methods

I declare a button in the Main Activity, but get NullObjectReference when I run the app. No matter where I try to move the declaration (outside of the class, inside the onCreate method, etc.), it redlines either the declaration or the button reference. I see posts recommending status versus non-static classes/methods, but I'm new to OOP and not exactly sure how to implement that. Can anyone tell me what I'm doing wrong?
public class MainActivity extends AppCompatActivity {
…
// Declare button in the MainActivity
Button btnWrong = (Button)findViewById(R.id.btnWrong);
...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// WHEN USER TAPS ITEMS ON APPBAR
switch (item.getItemId()) {
case R.id.mnuLoad: // If use taps "Load"
final Dialog dialog = new Dialog(MainActivity.this); /
…
btnLoad.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deckNumber = deckPicker.getValue();
if … }
dialog.dismiss();
btnWrong.setEnabled(true); // Trying to reference the button here
You have to do this:
outside onCreate() (under public class MainActivity extends AppCompatActivity)
Button btnWrong; //Declare button as private
in onCreate()
btnWrong = (Button)findViewById(R.id.btnWrong);
Now you can use btnWrong anywhere in its class
Try this:
public class MainActivity extends AppCompatActivity {
// Declare as class field
Button btnWrong;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.YOUR_LAYOUT_XML);
btnWrong = (Button)findViewById(R.id.btnWrong);
}
....
}

Set text on a textview instantiated in main activity

I have a main activity class which instantiates the variables for my widgets and makes references to them with findViewById. I would like to be able to set the text on a textview from a separate class, however eclipse complains that the variables cannot be resolved. I have set the main activity widget variables to public. Sorry if this is a silly question, I'm new to android.
public class MainActivity extends Activity {
public TextView player1ScoreView;
public TextView player2ScoreView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player1ScoreView = (TextView) findViewById(R.id.player1ScoreTextView);
player2ScoreView = (TextView) findViewById(R.id.player2ScoreTextView);
}
}
public class GamePlay {
...
player1ScoreView.setText(num.format(player1score));
}
player1ScoreView isn't recognized in the separate class. Does GamePlay have to be an activity to be able to set the text on a widget? Please explain. Thanks in advance
Your instance of the GamePlay class must have a reference to your MainActivity object in oder to access its members.
public class GamePlay {
...
MainActivity main = ...
....
main.player1ScoreView.setText(num.format(player1score));
}
Of course it would be better to access is via a getter method.
I'm not sure how you'll pass the reference of the MainActivity to your GamePlay object. It depends on how you create that object.
You would need to send an instance of the TextView to the other class or return the value to set and set it in the Activity.
So, you could get an instance of that class then send the TextView to a method of that class and set it there.
gamePlay.setScore(player1ScoreView);
and in the class
public void setScore(TextView tv)
{
tv.setText(num.formatplayer1score);
}
Or get the text to set from the gameplay class with something like
player1scoreview.setText(gameplay.getScore());
then have a method getScore() in your GamePlay class which would return a String to set the text as.
Simple option is to pass TextView object(player1ScoreView) as a parameter in GamePlay class method. By passing this object you can set value for this object through this method of GamePlay class.
Refer code below:
public class MainActivity extends Activity {
public TextView player1ScoreView;
public TextView player2ScoreView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player1ScoreView = (TextView) findViewById(R.id.player1ScoreTextView);
player2ScoreView = (TextView) findViewById(R.id.player2ScoreTextView);
GamePlay gamePlay=new GamePlay();
gamePlay.setViewValue(player2ScoreView);
}
}
public class GamePlay {
...
public void setViewValue(TextView player2ScoreView)
{
player2ScoreView.setText(num.format(player1score));
}
}

OnClickListener super

Why can I not pass this as Context in following code?
I am getting error
The constructor DataManager(new View.OnClickListener(){}) is undefined
I am new to android programming, so sorry if question is weird!!
Any help would be great.
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.d("vkx", "clk insert");
String qq="insert into users(id,name,password) values ('6','usrs','passs')";
DataManager dm=new DataManager(this);
dm.SqliteExecutenonquery(qq);
Log.d("vkx", "clk insert done");
}
});
I have my DataManger class
public DataManager(Context cont) {
super(cont, DBname, null, DBver);
}
....
So what you are doing is when instantiating DataManager, You are not passing a context as a paramater but actually your instance of OnClickListener.
DataManager dm=new DataManager(YOUR_CLASS_NAME.this);
YOUR_CLASS_NAME should be the Activity class name. ie
class MyClass extends Activity{
public onCreate(Bundle savedInstanceState){
Button btn = new Button();
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
DataManager dm=new DataManager(MyClass.this);
}
});
}
}
Give this a try and let me know how it goes
Just write MyClassName.this, assuming that 'MyClassName' is the Name of your Activity.
before setOnClickListener add this line:
final Context ThisContext = this;
and in your listener use this
DataManager dm=new DataManager(ThisContext);
You have written anonymous class new OnClickListener() {
There is no constructor for DataManager class with OnClickListener as type parameter.
I think instead of this, you need use getApplicationContext();
"this" is a reference to the current instance of the containing class.
Where you have used "this", it refers to an instance of an anonymous inner class of type onClickListener.
I believe that you might be wanting to pass the context of the Activity defining the onClickListener? If so, use MyActivity.this, where MyActivity is the name of the Activity class.

How to update a TextView of an Activity from another class

I am new to Android/Java programming. I have two classes, one is an Activity and the other is a normal class. My activity class contains a TextView. Can I update the TextView of the activity class from a normal class? I tried with random code, but it fails.
// 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");
}
}
}
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");
}
The preceding two examples require TextView to be used directly within the other class. However, there are cases where TextView shouldn't be present in the other class, e.g., your ClassB is used to update various Activities, where some activities update TextViews, and others might update EditTexts.
Hence, the below solution can guide you on how you could decouple your TextView from other classes, yet, you could still achieve what you want. It's using the interface approach.
Firstly, declare an interface where you could have ClassB communicate to the Activity, and call it MyCallback:
public interface MyCallback {
// Declaration of the template function for the interface
public void updateMyText(String myString);
}
Next in your Activity, implement MyCallback, and hence its function definition. In this function, you will receive the String from ClassB that you could do whatever you like, e.g., update the TextView (or EditText, etc.):
public class MyActivity extends AppCompatActivity implements MyCallback {
// ... whatever code of your activity
#Override
public void updateMyText(String myString) {
((TextView)findViewById(R.id.text)).setText(myString);
}
}
Lastly, 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 to update its TextView through the updateMyText function:
public class ClassB {
MyCallback myCallback = null;
public ClassB(MyCallback callback) {
this.myCallback = callback;
}
public void doSomething() {
// Do something to get String
String myString = str;
if (myCallback != null) {
myCallback.updateMyText(myString);
}
}
}
Hope this helps better show the architected structure of decoupling the Activity properly from ClassB.
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<T> class, which has a subclass called MutableLiveData<T>.
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<MyData> data = new MutableLiveData<>();
public LiveData<MyData> 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 BaseActivity {
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.
Beware that you should also persist the data to onSaveInstanceState(Bundle so that it is not lost (assuming the data is not from disk).
To do that, you need to do the following:
public class BaseActivity extends AppCompatActivity {
DataRepository dataRepository;
private static boolean didRestoreGlobals = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
MyApplication app = (MyApplication)getApplicationContext();
dataRepository = app.getDataRepository();
super.onCreate(savedInstanceState);
if(!didRestoreGlobals) {
didRestoreGlobals = true;
if(savedInstanceState != null) {
dataRepository.restoreState(savedInstanceState.getBundle("dataRepository"));
}
}
}
#Override
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBundle("dataRepository", dataRepository.saveState());
}
}
And then add saveState/restoreState methods to DataRepository accordingly.
If you are creating an object of your other class(ClassB)inside activity class, the simplest solution is to pass the TextView through constructor (if you aren't create an object in the activity class this answer will not be helpful). So your example should be like below:
// activity class
public class MainMenu extends Activity {
public TextView txtView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
txtView = (TextView)findViewById(R.id.text);
//instantiating a object of the ClassB and passing tv
ClassB obj = new ClassB(txtView);
}
}
// other class
public class ClassB {
//declarre tv
TextView txtView;
//get the tv as arg
public ClassB(TextView tv){
txtView = tv;
}
public void Update(){
txtView.setText("Hello");
}
}
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");
}
I have a XML page (Bert.XML) with four TextViews with ID's TextView1id, TextView2id, TextView3id and TextView4id
<GridLayout
android:id = "#+id/gridLayout"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:paddingTop="10dp">
<TextView
android:id = "#+id/TextView1id"
android:layout_gravity="end"
android:hint = "#+id/Risico"
android:textSize="#dimen/edit_size"
android:layout_height = "wrap_content"
android:layout_width = "fill_parent"
android:layout_column = "0"
android:layout_row = "1"
android:layout_columnSpan = "3"
/>
<TextView
android:id = "#+id/TextView2id"
android:layout_gravity="end"
android:hint = "#+id/Risico"
android:textSize="#dimen/edit_size"
android:layout_height = "wrap_content"
android:layout_width = "fill_parent"
android:layout_column = "0"
android:layout_row = "2"
android:layout_columnSpan = "3"
/>
<TextView
android:id = "#+id/TextView3id"
android:layout_gravity="end"
android:hint = "#+id/Risico"
android:textSize="#dimen/edit_size"
android:layout_height = "wrap_content"
android:layout_width = "fill_parent"
android:layout_column = "0"
android:layout_row = "3"
android:layout_columnSpan = "3"
/>
<TextView
android:id = "#+id/TextView4id"
android:layout_gravity="end"
android:hint = "#+id/Risico"
android:textSize="#dimen/edit_size"
android:layout_height = "wrap_content"
android:layout_width = "fill_parent"
android:layout_column = "0"
android:layout_row = "4"
android:layout_columnSpan = "3"
/>
</GridLayout>
The code for this view is shown below. In here I change the text of the TextViews through the Mail Class. The Activity has been given as a parameter for the Mail Class
package nl.yentel.finekinney;
import android.app.Activity;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.TextView;
public class Bert extends AppCompatActivity {
private TextView theObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bert);
//both findViewByID work
theObject = this.findViewById(R.id.TextView2id);
theObject = findViewById(R.id.TextView2id);
Mail theMail=new Mail();
theMail.activity=this;
theMail.NameOfObject="TextView2id";
theMail.KindOfObject="TextView";
theMail.Mail();
CalculateFromClass(this);
Calculate(this);
}
//Calculate(dezeActiviteit);
public void Calculate(Activity dezeActiviteit) {
//here you should include dezeActiviteit which can be called from the Class
theObject = dezeActiviteit.findViewById(R.id.TextView1id);
theObject.setText("text from method");
}
public void CalculateFromClass(Activity dezeActiviteit) {
//here you should include dezeActiviteit which can be called from the Class
theObject = dezeActiviteit.findViewById(R.id.TextView4id);
theObject.setText("text from Class");
}
}
My Mail Class looks like this
package nl.yentel.finekinney;
import android.app.Activity;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class Mail extends AppCompatActivity {
public String NameOfObject;
public String KindOfObject;
public Activity activity;
void Mail() {
//if the name and kind has been given as an input parameter
int ressourceId = activity.getResources().getIdentifier(NameOfObject, "id", activity.getPackageName());
if (KindOfObject.equals("TextView")) {
TextView TextViewObject = activity.findViewById(ressourceId); //VISArB 14
TextViewObject.setText("this is a TextView");
}
if (KindOfObject.equals("EditText")) {
EditText EditTextObject = activity.findViewById(ressourceId); //VISArB 14
EditTextObject.setText("this is an EditText");
}
//if the name is hard coded
TextView TextViewObject;
TextViewObject = activity.findViewById(R.id.TextView3id);
TextViewObject.setText("Hard coded ID");
//if I want to run a method from my main Class
Bert dezeBert = new Bert();
dezeBert.CalculateFromClass(activity);
}
}
This is kotlin code to access the view inside another layout :
//inflate layout
val view = inflate(this, R.layout.ly_custom_menu_item, null)
//access view inside the inflated
val tv = view.findViewById<AppCompatTextView>(R.id.txtV_WalletBalance_SideMenu)
//set value to view
tv.text = "Value"
//Add inflated Layout to something
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");
}
}
This can be manage easily in simple to steps.
================================
1) Activity to Multiple Fragment
below line can write in Fragment class Via FindViewById
((TextView) ((Activity) getActivity()).findViewById(R.id.textview)).setText("");

Categories