pass UI Controls from activity to a class - android

I stuck at this issue many times and I passed the problem in different ways and I'm not sure that I made it in the right way.
I simplified the problem in a the following example. I know that I can pass only the data to the class but I do want to pass the editText cause I have this problem with more difficult UI controls.
mainactivity.java
public class mainactivity extends Activity {
public EditText clickEditText;
int count =0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
newTxt();
}
public void newTxt() {
txt = new MyText(context);
txt.updateTextEdit("Main Activity");
}
}
myText.java
public class MyText
{
private Context _context;
// constructor
public MyText(Context context)
{
_context = context;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)findViewById(_context.R.id.editTextClick); // ????
strEditText.setText(str + " and myTxt");
}
}
if you could explain me how to fix the updateTextEdit function. i passed the context of the main activity. How can I change the editText? Thank you very much!!!

If you really want to do this this way, you need to save a reference to Activity, not Context. Like this:
public class MyText
{
private Activity _activity;
// constructor
public MyText(Activity activity)
{
_activity= activity;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)activity.findViewById(R.id.editTextClick);
strEditText.setText(str + " and myTxt");
}
}
and in newTxt() you will need to change:
txt = new MyText(context);
to:
txt = new MyText(this);
But wouldn't it be easier to just put this method inside your activity? Why do you want it in another class? If it really needs to be in another class, you could make that class an inner class of your activity and you would still have access to the activity's methods and member variables.

There's a similar question here
How to access Activity UI from my class?
You didn't say how you obtained the context, you should use this and get the mainactivity in the other class. not context.
then you can call runOnUIThread to perform UI updates.

Related

Main Activity Listener in a Custom View?

Hey I am trying to get real time data change in the main activity in my custom view. I want to implement a listener for the view, such that whenever anything changes in my Main Activity, my View gets to know about that and act accordingly.
Following is in my Main Activity.
public void setChangeListener(OnChangeListener onChangeListener){
this.onChangeListener = onChangeListener;
}
public interface OnChangeListener{
void currentRadius(int r);
void currentSpeed(int s);
}
I have initialized the same in View as,
public CustomView extends View{
//CONSTRUCTORS
//EVERYTHING ELSE
//These are inside the init(Context context) method.
MainActivity mainActivity = new MainActivity();
mainActivity.setOnChangeListener(new MainActivity.OnChangeListener() {
#Override
public void currentR(int r) {
Log.d("R", ""+r);
}
#Override
public void currentS(int s) {
Log.d("S", ""+s);
}
});
}
But this is giving me NullPointerException at
onChangeListener.currentR(//INTEGER VALUE);
onChangeListener.currentS(//INTEGER VALUE);
which are inside a onProgressChanged Listener.
What I want to ask is that is it even possible to send data using Listeners from Activity to View? If yes, then any pointers would be appreciated. Thanks.
In MainActivity
CustomView mCustomeView = new CustomView(this); // or Resource id
Create methods in CustomView
public void currentR(int r) {
Log.d("R", ""+r);
}
public void currentS(int s) {
Log.d("S", ""+s);
}
Then call that methods from MainActivity
mCustomeView.currentR(integervalue);
mCustomeView.currentS(integervalue);
NOTE:Be sure that if you change UI from that methods. It will be in Main UI Thread . other wise it will throw error
Hope This help
MainActivity mainActivity = new MainActivity();
Do not instantiate an Activity. Pass MainActivity context to the view and use that to do operations.
sample context
Context context = MainActivty.this;

Add view outside of onCreate in android

How can I add view bye function, outside of onCreate() in Android ?
My MainActivity.java
public class Main extends Activity {
static RelativeLayout mainRel;
static LinearLayout ll;
static TextView title;
static Context context;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RelativeLayout mainRel=(RelativeLayout) findViewById(R.id.mainRel);
}
public static void refresh(){
LinearLayout ll = new LinearLayout(this); // actually "this" just works in onCreate;
TextView title = new TextView(this);// actually "this" just works in onCreate;
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.addView(title);
title.setText("TV");
mainRel.addView(ll);
}
}
}
Thanks in advance
Usually, UI-related operations are not done in static methods. If you remove the static keyword, the this pointer will work even outside onCreate().
If you insist on keeping the static keyword (because you need the method to be static) then, you should pass a Context parameter to the method, by changing it to refresh(Context context)
Edit: if you need to call this method from another class, you might want to create a reference to your Main Activity and pass it to this other class, then call myMainActivity.refresh()
Calling static method is really bad idea.
Instead you can provide reference of the Activity to your AsyncTask in constructor. Then call non-static refresh() method from AsyncTask#onPostExecute().
When you store reference to Activity in AsyncTask use WeakReference. In case your activity is destroyed while background task is working, it won't be held in memory till background ends.
public class YourAsyncTask extends AsyncTask<Void, Void, Void> {
private WeakRefrence<Main> mainRef;
public YourAsyncTask(Main activity) {
mainRef = new WeakReference<Main>(activity);
}
protected void onPostExecute(Void result) {
Main main = mainRef.get();
if (main != null) {
main.refresh();
}
}
}

finish() not finishing the activity: Android

I have an Activity in whose onCreate() method i call a Utility function.
This utility functions requires a callback class instance as a parameter, in which it returns the info that i need. this is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utility.functionA(new functionACallBack() {
/**
*
*/
private static final long serialVersionUID = -7896922737679366614L;
#Override
public void onResponse(String error) {
((MyActivity) AppClass.getAppContext()).finish();
}
});
}
Once I have obtained that info, I want to close the activity. so i called finish() from inside the anonymous class that i created for the callback.
But the activity is not getting finished. I thought maybe i need to call finish() from UI thread so i did runOnUiThread(), in inside it also i tried calling finish(). But it just doesn't work.
Could someone please help me with this issue?
UPDATE:
I am storing APP context and then trying to use that but to no avail.
public class AppClass extends Application {
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
AppClass.mContext = getApplicationContext();
}
public static Context getAppContext(){
return AppClass.mContext;
}
}
Simply call something like this:
#Override
public void onResponse(String error) {
((Activity) context).finish();
}
As this is a static function, you'll have to be able to access your Context in a static way. You can save that as a Class variable, but you'll have to be aware about its handling as it might lead to memory leaks.
To avoid them, you can declare a class that extends Application and save here your context, so this way you won't ever have a memory leak.
Try using this code:
((Activity) ActivityClass.this).finish();
Remember, use the Activity class, not the Application one.

Share the object on real-time, singeltond pattern

I simply have not found a solution to share a real-time data between the activitys. My first activity receives real-time object (type double, a random numbers). And i want to pas this numbers to second activity. It all works, only the second Activity shows only one time the data. I have to refresh the activity by going back to first activity and only then the second activity show the latest data. I implemented a Singelton pattern:
public class FirstActivity extends Activity{
public double xAxis;
public double yAxis;
public static FirstView instance;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.device_view);
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
int data1 = msg.arg1;
xAxis = (double) data1;
dataX.setText(String.valueOf(xAxis));
int data2 = msg.arg2;
yAxis = (double) data2;
dataY.setText(String.valueOf(yAxis));
}
};
secondview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent nextScreen = new Intent(getApplicationContext(),
SecondActivity.class);
startActivity(nextScreen);
}
});
}
public static void initInstance(){
if(instance == null)
{
instance = new FirstActivity();
}
}
public static FirstActivity getInstance(){
return instance;
}
}
SecondView class
public class SecondActivity extends Activity{
private double valueX;
private double valueY;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linegraph);
valueX = FirstActivity.getInstance().xAxis;
valueY = FirstActivity.getInstance().yAxis;
}
}
Application class
package com.bluetoothcomm;
import android.app.Application;
public class MyApplication extends Application {
#Override
public void onCreate(){
super.onCreate();
initSingeltons();
}
public void initSingeltons(){
FirstActivity.initInstance();
}
}
You may implement a background service capable of providing the real time data to Activity1 and also to Activity2. I am guessing that your problem ocurrs if you are passing data from Activity1 to Activity2 through an Intent with putExtras, on this way it will only do this at the moment you start Activity2.
I have found my problem and the solution is to use Application. Only this dose not solves my problem. The problem is that the static variable instance public static FirstView instance is bound to the class loader, the first class that initilize that. So when the static variable inside any class has been initilized by an Activity and when the second Activity is started the first Activity is destroyed, so this means the static variable is also uninitilized. Thats why the SecondActivity dose not gets the up to date data or real time data, it catches only static constant data.
I changed my code a littele bit with the combination of Singelton and Application, couse this way the static variable should never be uninitilized when SecondActivity is activated. But i still get the same results, the static variable instance is uninitilized when i swtich to Second Activity. I am doing somethink wrong, does any one sees it. I added my code.
#Max Rasguido, #Orabig
You should use the intent process. docs
How is your data supposed to change when activity2 is shown, if you say that it's received by activity1 ?
However, I would use a preference, or an attribute of your application class (which is a singleton itself), but you give too little informations to fully understand your needs...

best way to handle resources

I was kind of stuck trying to pass the resources to a subclass used on my Activity. I solved it in two ways, but not sure if one or both will lead to possible memory leaks. So here is what I have so far:
-myactivity (the activity class)
-global (global class to the package, I'm using to to save global accesible variables)
-subclass (the subclass where I want to use a drawable resource)
a)
public class global{
public static Resources appRes;
....
}
public class myactivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
global.resApp = this.getResources();
...
}
private void somewhere(){
subclass tmp = new subclass();
tmp.subclasmethod();
}
}
public class subclass{
public subclass(){...}
public void subclassmethod(){
Bitmap bmp = BitmapFactory.decodeResource(Global.appRes, R.drawable.myres);
...
}
}
b)
public class myactivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
private void somewhere(){
subclass tmp = new subclass(this.getContext());
tmp.subclasmethod();
}
}
public class subclass{
Context context;
public subclass(Context context){
this.context = context
...
}
public void subclassmethod(){
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.myres);
...
}
}
Thanks in advance for you feedback.
If you want a global class to store application-wide values, you should at least not use your option a. Instead, take a look at the Application class, which is meant to help you with exactly this:
Base class for those who need to
maintain global application state.
Otherwise, the alternative you suggest in option b is an OK way to do it. At least if all you need is to pass along a reference to your application context so that you can access the resources.

Categories

Resources