I have a fragment MyFragment
public class MyFragment extends Fragment {
//Some code here like to constructor
//Trying to pass an object to another Activity
Intent i = new Intent(getActivity(), NextActivity.class);
startActivity(i);
i.putExtra("test", parcableObject);
getActivity().finish();
}
And I have an activity NextActivty
public class NextActivity extends AppCompatActivity {
//Some code here like to constructor
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next_activity);
Intent intent = getIntent();
mBoard = intent.getParcelableExtra("test");
Log.d(TAG, "onCreate: " + mBoard);
}
Here is my Board class
public class Board implements Parcelable {
//Implements all the Parcelable methods.
protected Board(Parcel in) {
//Auto-generated code here
}
public static final Creator<Board> CREATOR = new Creator<Board>() {
//Auto-generated code here
}
#Override
public int describeContents() {
//Auto-generated code here
}
#Override
public void writeToParcel(Parcel dest, int flags) {
//Auto-generated code here
}
}
My mBoard is always null.
Is there something I am not doing right here ?
You put your extra in wrong order. Put it before you start your activity.
public class MyFragment extends Fragment {
//Some code here like to constructor
//Trying to pass an object to another Activity
Intent i = new Intent(getActivity(), NextActivity.class);
i.putExtra("test", parcableObject);
startActivity(i);
getActivity().finish();
}
Related
Currently using an Intent with startActivity() to switch between 2 activities which share an abstract superclass. However, whenever startActivity() is called the custom object inherited from the abstract superclass gets reset. Is there anyway to maintain this object between startActivity() calls? Serializing the object with OnSavedInstanceState does not work because this object contains a LinkedList.
Every time a class is created regardless if it extends a superclass (in this case an Activity), the superclass is recreated. You would extend the Activity to share common methods/functions and imports....
You want to stay away from Serializable, so you want your object class to implement Parcelable:
public class CustomObject implements Parcelable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
}
public CustomObject() {
}
protected CustomObject(Parcel in) {
this.name = in.readString();
}
public static final Parcelable.Creator<CustomObject> CREATOR = new Parcelable.Creator<CustomObject>() {
#Override
public CustomObject createFromParcel(Parcel source) {
return new CustomObject(source);
}
#Override
public CustomObject[] newArray(int size) {
return new CustomObject[size];
}
};
}
In the first activity you want to pass the List to the second Activity using an Intent:
public class StartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(StartActivity.this, ReceiveDataActivity.class);
i.putParcelableArrayListExtra("KEY", getCustomObjectList());
startActivity(i);
}
});
}
private ArrayList<CustomObject> getCustomObjectList() {
ArrayList<CustomObject> itemList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
CustomObject customObject = new CustomObject();
customObject.setName("Name " + i);
itemList.add(customObject);
}
return itemList;
}
}
Then to get the list you would use getIntent():
public class ReceiveDataActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive_data);
List<CustomObject> itemList = getIntent().getParcelableArrayListExtra("KEY");
Toast.makeText(this, "List size = " + itemList.size(), Toast.LENGTH_SHORT).show();
}
}
I have the MainActivity that a want to communicate with a class using an interface.
public interface MyInterface(){
public void doAction();
}
In my MainActivity I will have this piece of code:
public class MainActivity extends AppCompatActivity implements MyInterface(){
//....some more code here
#Override
public void doAction() {
//any code action here
}
//....some more code here
}
So now, If I have another class (NOT ACTIVITY), how should I correctly make the link between class---interface---mainActivity??
public class ClassB {
private MyInterface myinterface;
//........
//...... how to initialize the interface
}
I am confused about how to initialize and use the interface in ClassB
In the constructor of other class: ClassB, accept interface as argument and pass reference of Activity, hold that object in your Activity.
like so:
public class MainActivity extends AppCompatActivity implements MyInterface()
{
private ClassB ref; // Hold reference of ClassB directly in your activity or use another interface(would be a bit of an overkill)
#Override
public void onCreate (Bundle savedInstanceState) {
// call to super and other stuff....
ref = new ClassB(this); // pass in your activity reference to the ClassB constructor!
}
#Override
public void doAction () {
// any code action here
}
}
public class ClassB
{
private MyInterface myinterface;
public ClassB(MyInterface interface)
{
myinterface = interface ;
}
// Ideally, your interface should be declared inside ClassB.
public interface MyInterface
{
// interface methods
}
}
FYI, this is also how View and Presenter classes interact in MVP design pattern.
public class MainActivity extends AppCompatActivity implements
MyInterface
{
OnCreate()
{
ClassB classB= new ClassB(this);
}
}
public class ClassB
{
private MyInterface myinterface;
public ClassB(MyInterface myinterface)
{
this.myinterface=myinterface;
}
void anyEvent() // like user click
{
myinterface.doAction();
}
}
public class MainActivity extends AppCompatActivity implements MyInterface(){
private ClassB ref;
#Override
public void onCreate (Bundle savedInstanceState) {
ref = new ClassB();
ref.setMyinterface(this);
}
#Override
public void doAction () {
// any code action here
}
}
public class ClassB{
private MyInterface myinterface;
public setMyInterface(MyInterface interface){
myinterfece = interface;
}
public interface MyInterface{
// interface methods
}
}
//-------------------------------------
//Two way communication using Interface
//-------------------------------------
//A. Interfaces
//Communicator Interface ( Activity to Fragment )
public interface CommunicateToFragment {
public void CallBack(String name);
}
// Communicator Interface ( Fragment to Main )
public interface CommunicateToMain {
public void respond(String data);
}
//B. Main Class implements CommunicateToMain Interface
//Use CommunicateToFragment interface to send data in FragmentA
public class MainActivity extends AppCompatActivity implements CommunicateToMain {
private CommunicateToFragment communicateToFragment;
public void setCommunicateToFragment(CommunicateToFragment communicateToFragment) {
this.communicateToFragment = communicateToFragment;
}
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void respond (String data) {
communicateToFragment.CallBack("Callbacked when onCreate method Created" + data);
Log.d("test","get result from fragment: " + data);
FragmentManager manager = getFragmentManager();
FragmentB f2 = (FragmentB) manager.findFragmentById(R.id.id_fragment2);
f2.changeText(data);
}
}
//C. FragmentA implements CommunicateToFragment
//Use CommunicateToMain interface to send data in MainActivity
public class FragmentA extends Fragment implements View.OnClickListener, CommunicateToFragment{
Button button;
int counter=0;
CommunicateToMain commToMain;
#Nullable
#Override
public View onCreateView (LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a,container,false);
}
#Override
public void onActivityCreated (#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
commToMain = (CommunicateToMain) getActivity();
button = getActivity().findViewById(R.id.button);
button.setOnClickListener(this);
if(getActivity() instanceof MainActivity){
((MainActivity) getActivity()).setCommunicateToFragment(this);
}
}
#Override
public void onClick (View view) {
counter++;
commToMain.respond("The button was clicked" + counter + " Times");
}
#Override
public void CallBack(String name) {
Log.d("test","get result from main activity: " + name);
}
}
I am trying to pass a simple String from #EActivity to #EFragment , so i can later on assign that value to textView in #EFragment , I don't want to use saving in bundle pattern
My attempt:
#EActivity(R.layout.activity_pre_plan_detail)
public class PrePlanDetailActivity extends AppCompatActivity {
// some long adapter code
#AfterViews
void inits_(){
adapter.addFragment( myFragment_.builder().build().setme("something"));
}
}
______________________________________________________________________________
#EFragment(R.layout.fragment1)
public class PlanDescription extends Fragment {
#ViewById
TextView tv_fpd_description;
public void setme(String data){
tv_fpd_description.setText(data);
}
}
output/error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Note: All mentioned annotations are part of boilerplate library [android annotation][1]
Try with local broadcast manager
**Activity code:**
-----------------
Intent intent = new Intent("my-custom-event");
intent.putExtra("message", "something");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
**fragment code:**
-------------------
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onReceiver , new IntentFilter("my-custom-event"));
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onReceiver );
super.onDestroy();
}
**BroadCastReceiver:**
private BroadcastReceiver onReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String data= intent.getStringExtra("message");
tv_fpd_description.setText(data);
}
};
You should really use a Fragment argument for this:
#EFragment(R.layout.fragment1)
public class PlanDescription extends Fragment {
#FragmentArg
String someDescription;
#ViewById
TextView tv_fpd_description;
#AfterViews
void afterViews() {
tv_fpd_description.setText(someDescription);
}
}
And you can create the Fragment like this:
PlanDescription_.builder().
someDescription("your data")
.build();
How can i make a callback to an Activity form a Java Class?
Example:
public class TestClass{
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
}
}
When sendToSomeActivity() is called, i want to make a callback to the already started SomeActivity and pass some text to the Activity. In SomeActivity i want to use the text.
Note: The TestClass object that i want to use is already created in another class.
How can this be done?
The solution I chose is as follows:
Use BroadcastReceivers to communicate between Java classes and Activities.
Example:
public class SomeActivity extends Activity{
private MyBroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receiver = new MyBroadcastReceiver();
this.registerReceiver(receiver, new IntentFilter(MyBroadcastReceiver.ACTION));
}
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(receiver);
}
private class MyBroadcastReceiver extends BroadcastReceiver{
public static final String ACTION = "com.example.ACTION_SOMETHING"
#Override
public void onReceive(Context context, Intent intent) {
String test = intent.getStringExtra("dataToPass");
}
}
}
public class TestClass{
private String test = "TEST";
private Context context;
public TestClass(Context context){
this.context = context;
}
private void sendToSomeActivity(){
Intent intent = new Intent();
intent.setAction(SomeActivity.MyBroadcastReceiver.ACTION);
intent.putExtra("dataToPass", test);
context.sendBroadcast(intent);
}
}
Try this..
public class TestClass{
interface Implementable{
public void passData(String text);
}
Implementable imple;
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
if(imple != null){
imple.passData(text);
}
}
public void setListener(Implementable im){
imple = im;
}
}
class SomeActivity implements Implementable{
new TestClass().setListener(this);
#override
public void passData(String text){
//here is your text
}
}
In your java class create an interface like this
public class TestClass{
private MyInterface myInterface;
public interface OnSendSomething {
public void onSending(String sendWhateverYouWant);
}
public void setOnSendListener(MyInterface myInterface) {
this.myInterface = myInterface;
}
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
myInterface.onSending(sendWhateverYouWant);
}
And in your activity do something like this:
TestClass tclass = new TestClass(context);
tclass.setOnSendListener(new OnSendSomething () {
#Override
public void onSending(String sendWhateverYouWant) {
//sendWhateverYouWant is here in activity
}
});
You can also visit these links for better understanding.
How to create our own Listener interface in android?
Observer Design Pattern in Java
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