Is there any way in which I can move a bundle of data from one class to another without actually changing the layout?
For example:
I have 3 classes: class A, B and C.
Now class B has navigation drawer and bottom navigation menu implemented which can be seen on class A and C and also be used at the same time.
However, I have a button in the bottom navigation menu which takes me to class C but the data which I need to view in this is in class A.
Is there any way by which I can just send a bundle of data to class B but without using intents, then retrieve the data from class B and show it on class C?
** EDIT **
P.S : B is an AppCombatActivity extended class and A and C are Fragment extended classes.
Your question is very simple to implement but it can also become a headache. This is what you should do.
class A:
public class A extends Activity {
static A INSTANCE;
String data="A";
#Override
public void onCreate(Bundle savedInstanceState) {
INSTANCE=this;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static A getActivityInstance()
{
return INSTANCE;
}
public String getData()
{
return this.data;
}
}
class B:
public class B extends Activity {
String data;
#Override
public void onCreate(Bundle savedInstanceState) {
data=A.getActivityInstance().getData();
}
}
The trick is to create an Instance in class A and then using that instance to access all the public elements like methods, variables etc using that Instance.
Hope this helps :)
I would suggest using a SharedPreferences file to store the data in Class A. Then you can read from the SharedPreferences file wherever you want to show the data.
Refer this page -
https://developer.android.com/training/basics/data-storage/shared-preferences.html
You could use interface for passing data, this the reference
https://stackoverflow.com/a/9977370/2951976
Related
I have two classes named abc and def. Class abc has string named "paths" and function named "test". I can easily use the variable "paths" from another class "def" but can't seem to call the function "test" from class "def".
I have created an object of class abc in class def and tried to call the function but it doesn't work.
public class abc extends Activity {
String paths="path";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test("lol");
}
public void test(String name){
Toast.makeText(abc.this,name,Toast.LENGTH_LONG).show();
}
}
public class def extends Activity {
abc x= new abc();
String paths=x.paths;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(def.this,paths,Toast.LENGTH_LONG).show();// This is
//working
x.test("hahahas"); // Not working
}
}
i want the method "test" from class abc to be used by class def passing parameter from class def.
The problem is this
abc x= new abc();
You shouldn't be creating an instance of something that extends Activity in this way. You should be using startActivity or startActivityForResult
Also, you shouldn't be holding a reference to one activity inside an instance of another one at all, because activities are created and destroyed by Android so the reference you hold to it may go stale. See Android Activity Lifecycle`. Simply rotating your device is enough to make this happen.
From the tutorial "build your first app" we have start another activity, assuming that you do infact want to launch another activity. You need to learn about intents; let me quote from that link:
An Intent is an object that provides runtime binding between separate components, such as two activities. The Intent represents an app’s "intent to do something."
Thanks for all your comments. I found the solution. In class def, instead of extending Activity i used
public class def extends abc
making class "def" child class of "abc". And after the line
super.onCreate(savedInstanceState);
in class "def" i added one line shown below which did the job.
super.test("lol123");
Are the classes in the same package? (I assumeing that they are in the same package, because you dont have public infront of String paths)
If a method is public you should be able to call it from everywhere.
So i guess you have a problem in your test case.
try with classes, that do not extend Activity and only have the methods needed to test. Then extend your testcase further and further until it stops working.
Is the path variable final?
you might want to add public static final modifier to it.
I need to call a method in fragment when a certain item is selected in navigation drawer activity.
For this, I've created one interface which I Will be initializing & calling a method from the activity, Also I'll implement this interface in Fragment and override this method.
Here is code snippet for declaring an interface.
public interface AlertForDiscardDefaultProfileChanges {
void alertForDiscardDefaultProfileChanges(int navigationItemID);
}
And this is how I'm initializing in activity.
private AlertForDiscardDefaultProfileChanges alertForDiscardDefaultProfileChanges;
#Override
public void onCreate(Bundle savedInstanceState) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
alertForDiscardDefaultProfileChanges = (AlertForDiscardDefaultProfileChanges) this;
}
Here I'm getting java.lang.ClassCastException for initializing it.
Not sure what I'm missing here or what's wrong.
you have to implements this interface to your activity/fragment for eg :
MainActivity :
public class MainActivity extends AppCompatActivity implements FragmentClassName.AlertForDiscardDefaultProfileChanges{
//override methods
#Override
public void alertForDiscardDefaultProfileChanges(String navigationItemID) {
// now use navigationItemID here...
}
}
Here is how I achieved it,
I called a method through an object of a fragment in which I wanted to implement a method.
Fragment Class -
public class DefaultProfileFragment extends Fragment implements
AlertForDiscardDefaultProfileChanges {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_default_profile, container,
false);
mContext = view.getContext();
return view;
}
#Override
public void alertForDiscardDefaultProfileChanges(int navigationItemID) {
showDismissWarning(navigationItemID);
}
Activity from which I need to call interface method.
A Just simple object of a fragment class and name of a method. Nothing fancy needs to be done. No need to initialize an interface.
(new DefaultProfileFragment()).alertForDiscardDefaultProfileChanges(id);
Step-1
public interface AlertForDiscardDefaultProfileChanges {
void alertForDiscardDefaultProfileChanges(int navigationItemID);
}
define this method from which activity and class you want transfer your data
Step 2 -
Define this method also in step 1 class.
private AlertForDiscardDefaultProfileChanges favListner;
public void setAlertOnDiscardListner(AlertForDiscardDefaultProfileChanges
favOnTouchListner) {
favListner = favOnTouchListner;
}
Step -3 .
pass value from Step 1 class like below
favListner.alertForDiscardDefaultProfileChanges(int navigationItemID);
Step-4
In which class you want data first implement that interface like.
Class A implements YourActivity_where_interface define.AlertForDiscardDefaultProfileChanges{
override Method.
}
Step 5.
You Should have to do one thing also in that class where you want data .
You should have to initialise interface from on Create method like below.
YourActivity_where_interface define.setAlertOnDiscardListner(this);
Done now you can play with it.
I would like to make a Quiz app where I want my score variable to be inherited in each Activity.
I don't know how to perform that task.
Here is my MainActivity Code where I declared the global Variable.
public class MainActivity extends AppCompatActivity {
public int score=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View v)
{
Intent intent = new Intent(this,question1.class);
startActivity(intent);
}
}
Here is the class in which I want to inherit it :
public class question1 extends MainActivity {
MainActivity ma= new MainActivity();
ma.score;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
}
}
In Android it's not recommended that you use variables to store data across an application (it's also not possible to do that using inheritance), that is bad practice.
What you're trying to do:
Store some int as score in a parent class
In the sub-class inherit that score to do something
Why this is a problem:
First of all, inheriting this score will not allow you to modify it in any way in a subclass. Java doesn't allow you to override values of an inherited field. See this for info. Secondly, creating an inheritance relationship between classes just to get some data is very futile... Because inheritance will inherit everything from the parent class which is not what you need.
Solution:
Instead Android APIs have features like SharedPreferences and SQLite that give you options for storing data.
Why?
Because storing this data in SharedPreferences or SQLite can be almost seen as storing it in a global variable for you to use throughout your application whenever you need it. It's storage that gives you read/write whenever you want, and doesn't get destroyed when your application closes.
Please take a look at this for more information on the storage options Android provides.
public class RootActivity extends Activity
{
static LiLa superLayout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
main();
setContentView(superLayout);
}
private void main()
{
// LiLa is a class which extends LinearLayout
superLayout = new LiLa(this);
//DownloadData is an AsyncTask
DownloadData mDownloadData = new DownloadData(this);
mDownloadData.execute();
}
}
So the AsyncTask change some parts of the superLayout, for now in the AsyncTak, I do :
RootActivity.superLayout.tv.setText("hello");
Would it be better to change :
static LiLa superLayout;
to
LiLa superLayout;
and :
DownloadData mDownloadData = new DownloadData(this);
to
DownloadData mDownloadData = new DownloadData(this, superLayout);
So that it would be possible to do in the AsyncTask :
superLayout.tv.setText("hello");
So question is : is it better to access this kind of parameters (TextView tv for example) or a method to change this TextView through static way or via parameter ?
Thanks for reading me.
EDIT : btw in my code it is a bit more messy it could be more like
RootActivity.superLayout.class1.class2.tv.setText("hello");
It would be better to avoid using a static in this case, and if that means that you need to pass the value as a parameter, that's fine too. (Statics are not O-O, and are generally a bad idea in an O-O design. They also present problems in unit testing.)
It is also generally a good idea to declare all instance variables and provide getter and/or setter methods if that is required.
I don't think static access to a layout is the best way of doing it.
A better solution would be to save the layout as a private variable and then add your AsyncTask as an inner class of your activity:
public class RootActivity extends Activity
{
private LiLa superLayout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
main();
setContentView(superLayout);
}
private void main()
{
// LiLa is a class which extends LinearLayout
superLayout = new LiLa(this);
//DownloadData is an AsyncTask
new DownloadData().execute();
}
private class DownloadData extends AsyncTask<..., ..., ...> {
//You can reference the variable superLayout here.
//If you need the context, use RootActivity.this
}
}
I think access view in parameter is better way. SO we don't have to make any static reference for the class or activity.
Read the "A public static field/method" part of this link:
http://developer.android.com/resources/faq/framework.html#3
I hope this will help.
How do I access the method myMethod from another class?
public class controller extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
int myMethod() {int id = 0; return id;} //arbitrary example, may also be static?
}
You pass in your controller Activity to the other class, the way you would with any other object in Java. Just be careful not to hold onto an Activity in places that might cause garbage collection issues (e.g., a service, a static data member, a custom Application object).