How to access Activity UI from my class? - android

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

Related

adapter-like pattern for not AdapterView class

I need to transmit data from my activity layer to a view (or at least its fragment) that is not a child of AdapterView.
For a ListView, I could do this very easily with its adapter, but I am stuck on how to reproduce this behavior for a non AdapterView widget (for clarity, let's say a TextView).
I don't want to keep a reference to my fragment (or worse, the view) at Activity level.
Any ideas ?
One way to do this is to use java.util.Observable/Observer :
import java.util.Observable;
import java.util.Observer;
public class MyTextView extends View implements Observer{
#Override
public void update(Observable observable, Object data) {
this.setText((String)data);
}
}
Then, you need an Observable class :
import java.util.Observable;
public class MyObservable extends Observable {
public void setText(String text){
notifyObservers(text);
}
}
Activity :
public class MainActivity extends Activity {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
...
MyObservable mtv = new MyTextView(getApplicationContext());
MyTextViewModel mm = new MyTextViewModel(10);
mm.addObserver(mtv);
mm.setText("test");
// demonstrated in an activity to shorten the sample, but ideally you would
// keep the observer at activity level and manage the view in the fragment
}
}
------------------------------------------------
Another way to do this is through android.database.DataSetObservable to implement a more traditional Adapter like object :
public class CustomAdapter extends DataSetObservable {
String mText;
public String getText() {
return mText;
}
public void setText(String text) {
mText = text;
}
}
You manipulate it like any other adapter at Activity level :
public class MyActivity extends Activity {
private CustomAdapter mCustomAdapter;
#Override
protected void onCreate() {
...
mCustomAdapter = new CustomAdapter();
}
private void initializeFragment (Fragment fragment) {
// this or whatever method you use to setup your fragments
((MyFragment) fragment).setCustomAdapter(mCustomAdapter);
}
private void onDataLoaded (Stg data) {
// callback method invoked when the network thread has finished loading data
mCustomAdapter.setText(data.text);
mCustomAdapter.notifyChanged();
}
Finally, the only thing missing is the link between your fragment and the view :
public class MyFragment extends Fragment {
private CustomAdapter mCustomAdapter;
public setCustomAdapter(CustomAdapter adapter) {
// this method allows to setup the adapter at startup
mCustomAdapter = adapter;
}
protected DataSetObserver mMyViewObserver = new MyObserver();
private class MyObserver extends DataSetObserver {
#Override
public void onChanged() {
mUpdateHandler.sendEmptyMessage(0);
}
}
private Handler mUpdateHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
updateMyView();
}
};
private void updateMyView() {
if (mView == null) {
return;
}
mView.setMainTextViewText(mCustomAdapter.getText());
}
}
And here you have it. Each time you call notifyChanged(), your observer gets called. In return, he invokes the handler that update the view.
Here you have it, leak free, thread safe custom adapter for any kind of view.

how to call method in activity form non activity class

I have an Activity and non Activity class. How to call a method in Activity class from non Activity class
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
DataClass dc = new DataClass();
dc.show();
}
public void call(ArrayList<String> arr) {
// Some code...
}
}
public class DataClass {
public void show(ArrayList<String> array) {
// Here I want to send this ArrayList values into the call
// method in activity class.
MainActivity act = new MainActivity();
act.call(array);
}
}
Just create a callback interface inside the DateClass.
public DateClass {
public interface IDateCallback {
void call(ArrayList<String> arr);
}
private IDateCallback callerActivity;
public DateClass(Activity activity) {
callerActivity = (IDateCallback)activity;
}
...
}
public void show(ArrayList<String> array) {
callerActivity.Call(array);
...
}
//And implements it inside your activity.
public class MainActivity extends Activity
implements IDateCallback {
public void call(ArrayList<String> arr) {
}
}
Well there are several things you could do. I think the easiest for you would be to send the Context into DataClass like so:
DataClass dc =new DataClass();
dc.show(this);
And in your DataClass save the context into a global var Context context. Then use it like so:
((MainActivity)context).call(array);
((MainActivity)getContext).array();
Just make a singleton like:
TeacherDashboardSingleton:
public class TeacherDashboardSingleton {
public Teacher_Dashboard aa;
private static final TeacherDashboardSingleton ourInstance = new TeacherDashboardSingleton();
public static TeacherDashboardSingleton getInstance() {
return ourInstance;
}
}
myActivity class:
onCreate(....){
....
TeacherDashboardSingleton.getInstance().aa = this;
....
}
this will create an object of same instance as in activity
now you can use it from anywhere

Call a public method in the Activity class from another class?

MAIN ACTIVITY
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void Mymethod()
{}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyClass(Context context)
{
}
}
I tried to call Mymethod() from an instance of MyClass.
I would really appreciate any help. Thanks.
Why not just pass the activity to the constructor like
public class MyActivity extends Activity {
onCreate(){
MyClass myobj=new MyClass(MyActivity.this);
}
public void myMethod(){
}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass{
public MyClass(MyActivity act) {
act.myMethod();
}
}
Make that method as static so you can call without creating the class object
public static void Mymethod()
{}
and call like this way
MainActivity.Mymethod();
This is probably the best way to do it. This is how I'm doing it. It's called a Singleton Design Pattern:
public class MyActivity extends Activity {
private static MainActivity instance;
public static MainActivity getInstance() {
if(instance==null){
setInstance(this);
}
return instance;
}
public static void setInstance(MainActivity instance) {
MainActivity.instance = instance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setInstance(this);
}
}
If I'm understanding you correctly I believe you can solve your problems using an interface as a callback.
////ACTIVITY/////////////////////////////////
public class MyActivity() extends Activity {
onCreate()
{
MyClass myObj=new MyClass();
//Set the listener on the object. Created as anonymous
myObj.setListener(new MyClass.Listener() {
myMethod();
});
}
}
public void myMethod(){
}
//////Custom Class//////////////////
public class MyClass {
Listener mListener;
public interface Listener {
public void onInterestingEvent();
}
public void setListener(Listener listener) {
mListener = listener;
}
public void someUsefulThingTheClassDoes() {
//Do your code here and when you're ready to call the activity's method do this
mListener.onInterestingEvent();
}
}
I had an inner class that I wanted to pull out into a more general library "Helper" class. I had the same issue you do. I got around it by making the helper class abstract, with a single abstract method. Then in my project package I extended the helper class with a constructor call in the specific class.
public class MyActivity extends Activity {
onCreate() {
MyHelperClass = new MyHelperClass(this, "foobar");
}
public void myMethod() {
// Code...
}
}
// In a different file
public class MyHelperClass extends HelperClass {
private MyActivity mInstance;
public MyHelperClass(MyActivity act, String data) {
super();
this.mInstance = act;
this.mActivity = act; // Useful for calling generic Activity methods in the HelperClass
this.mData = data;
}
protected void callMyActivityMethod() {
mInstance.myMethod();
}
}
// In a different file
public abstract class HelperClass {
protected Activity mActivity;
protected String mData;
public HelperClass() {
// Subclass will set variables
}
protected abstract void callMyActivityMethod();
// More code for all the other stuff the class does
}
In this way, I have a helper class that contains the vast majority of the "work", and all I have to do is make a subclass with the constructor and one method in order to get access to the calling activity's method of interest.
You have to pass instance of MainActivity into another class, then you can call everything public (in MainActivity) from everywhere.
MainActivity.java
public class MainActivity extends AppCompatActivity {
// Instance of AnotherClass for future use
private AnotherClass anotherClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Create new instance of AnotherClass and
// pass instance of MainActivity by "this"
anotherClass = new AnotherClass(this);
}
// Method you want to call from another class
public void myMethod(){
...
}
}
AnotherClass.java
public class AnotherClass {
// Main class instance
private MainActivity mainActivity;
// Constructor
public AnotherClass(MainActivity activity) {
// Save instance of main class for future use
mainActivity = activity;
// Call method in MainActivity
mainActivity.myMethod();
}
}
In MainActivity.class file
You have to pass MainActivity context from MainActivity Class. Then in MyClass you have to Get MainActivity context. Remember Context and MyActivity are two different reference.
public class MyActivity extends Activity
{
onCreate(){
MyClass myobj=new MyClass(MyActivity context);
}
public void Mymethod(){}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyActivity context;
MyClass(MyActivity context)
{
this.context = context;
this.context.Mymethod();
//Or you can directly use activity context
context.Mymethod();
}
}
I decided to write the HelperClass MyClass as an inner class of MyActivity class. This allows it full access to parent class but the bad thing is now MyClass is restricted to MyActivity class only.
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void myMethod()
{
}
}
//INNER CLASS
public class MyClass
{
public MyClass()
{
}
//I can directly access the MyMethod
myMethod();
}

public static variable is accessible in second activity in android?

I am working in android. I have two acitivities in my project. I have declared a public static variable in one activity like this:-
public static String name="KUNTAL";
In my second activity i am trying to use this variable, then it is generating error that this name variable is not exist.
Is this possible to use a variable anywhere in my project if it is declared as public ?
Please suggest me what mistake i have done.?
Thank you in advance...
public class Activity1 extends Activity {
public static String name="KUNTAL"; //declare static variable.
#Override
public void onCreate(Bundle savedInstanceState) {
}
}
public class Activity2 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
Activity1.name; //way to access static variable using dot operator.
}
}
I think you must access them in a 'static way', i.e.:
String myVar= name; // wrong
String myVar= TheClassThatContainsName.name; // right
You can use the variable specified as public static in any Activity but you need to access that variable by using the Activity name where you Declared it.
For Accessing in Second Activity just use ;
Activity1.name ="Me";
means that name variable belongs to Activity1 and you are using in Acvity2
Declaring variables public static is not the recommended way of passing values between two activities. Use Intent object instead:
public class Activity1 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
yourButton.setOnClicklistener(listener);
}
}
//On click of some button start Activity2:
View.onClicklistener listener = new View.OnClickListener(){
#Override
public void onClick(View v) {
Intent mIntent = new Intent(Activity1.this,Activity2.class);
mIntent.putExtra("yourKey","yourValue");
startActivity(mIntent);
}
};
//and then in your activity2 get the value:
public class Activity2 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
String yourValue = getIntent().getExtras().getString("yourKey");
}
}
if you're using the same variable in more than one activity then make a class something like ActivityConsts{}, and declare and initialize this variable in there(in ActivityConsts). And access this variable from anywhere with the class name.
ex-
declare a class-
public class ActivityConsts {
//your String var
public static String name="KUNTAL";
}
now in your activity:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
String yourStringVar = ActivityConsts.name;
}
}
There is no datatype specified for your variable. Use
public static String name="KUNTAL";

Is it possible to use One UI Handler For more than One Activity?

Hi I want to use only single handler for more than one Activity.Can I do that ?
To add a bit to Octavian answer, you will actually have a single Handler class but one instance per activity.
For example:
public class MyHandler extends Handler {
// Keep a weak reference to the activity owning the handler
private WeakReference<Activity> activityRef;
public MyHandler(Activity a) {
this.activityRef = new WeakReference<Activity>(a);
}
public void handleMessage(Message msg) {
// do your stuff here, for instance, finish the activity
if (activityRef.get()!=null) {
activityRef.get().finish();
}
}
}
Then in your activity:
public class MyActivity extends Activity {
protected MyHandler handler;
public void onCreate() {
// This is where you'll re-use the handler code
handler = new MyHandler(this);
}
}
Of course. Create a new class that implements the desired interface and instantiate it where needed.
Lets take the OnClickListener as an example. Create a class ExternalClickListener.
public class ExternalClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
// Do whatever you want.
}
}
Now when you want to set it on a Button it'd be
btn.setOnClickListener(new ExternalClickListener());
Declare this Handler as a static and access it : MyClass.myHandler.

Categories

Resources