So my ListFragment is Tab2 and it looks something like this.
public class Tab2 extends ListFragment {
public interface MyFragmentListener {
public void onFragmentItemSelected(String CheckSwitch);
}
static MyFragmentListener myListener;
public static void setMyFragmentListener(MyFragmentListener listener) {
myListener = listener;
}
on some condition
if (TempTweet < CheckingTemp)
{
myListener.onFragmentItemSelected("TurnOn");
}
on Tab1
public class Tab1 extends Fragment implements Tab2.MyFragmentListener {
#Override
public void onFragmentItemSelected(String CheckSwitch) {
if(CheckSwitch.equals("TurnOn"))
{
//Some Actions
}
}
on MainActivity
Tab2.setMyFragmentListener(Tab1);
This answer has been taken from Passing value from ListFragment to another ListFragment now i am very new to Java and android so i am not sure it always says "Expression Expected"
You can make global static variable so that you can use it wherever you want.
Related
class Fragment extends Fragment() implements Callback {
#Ovverride
onCreate(SavedInstanceState savedInstanceState) {
Adapter adapter = new Adapter(getContext())
}
#Ovverride
someCallbackMethod() { // Code when callback is called }
}
class Adapter extends RecyclerView.Adapter<VH>() {
Context context;
public Adapter(Context context) {this.context = context}
class VH extends RecyclerView.ViewHolder {
private void bind() {
button.setOnClickListener (v-> {
BottomSheet sheet = BottomSheet.newInstance(variable);
sheet.show(((FragmentActivity) context).getSupportFragmentManager(),
sheet.getClass().getName());
})
}
}
class BottomSheet extends BottomSheetDialogFragment {
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
if (context instanceof Callback) listener =
(Callback) context;
else Log.v("BottomSheet", "Not instance");
}
}
Even though the main fragment implements the callback the context of that fragment is never the instance of the callback what might be the reason for this and how can it be fixed.
Note: There might be some errors here and there because I made a generic view of the classes.
A Fragment does not inherit from Context. Your easiest solution would be to implement your Callback in the Activity (which is a Context) that contains the Fragment.
I'm trying to adjust the observer pattern to my code, so in my case MSG0100 it's my Subject class that it updates the variable msg100PreselectionAplication, and the MainActivity class it's an concrete observer, and usually you have to create the Observer class, but my problem is that the MainActivity has to extend from that class and that's a problem because Java does not support multiple inheritance. Here is what i have until now, can some one give me an idea of what i need next? Please
MSG0100 class:
public class MSG0100 implements PreselectionAplicationUseCases {
private OnMsg100PreselectionChanged listener = null;
public void setOnMsgPreselectionChanged(OnMsg100PreselectionChanged listener) {
this.listener = listener;
}
public void setMsg100PreselectionAplication(boolean msg100PreselectionAplication) {
if(listener != null) {
listener.onPreselectionChanged(msg100PreselectionAplication);
}
}
}
interface OnMsg100PreselectionChanged {
void onPreselectionChanged(boolean isChanged);
}
Main activity class:
public class MainActivity extends AppCompatActivity {
private ExpandableListViewAdapter mExpandableListViewAdapter;
PreselectionAplicationUseCases preselectionAplicationUseCases;
public void Preselection(){
preselectionApplicationUseCases.setOnMsgPreselectionChanged(new OnMsg100PreselectionChanged {
#Override
void onPreselectionChanged(boolean isChanged) {
//do something with changed boolean
}
});
}
}
You should create Observer as an Interface which implemented by MainActivity like this:
interface Observer {
void update(Data data)
}
public class MainActivity extends AppCompatActivity implements Observer {
//…
#Override
public void update(Data data) {
// update your data to your UI here
}
//…
}
and modify your subject to receive observer
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
public class MSG0100 implements PreselectionAplicationUseCases, Subject {
private Data data = new Data();
private Observer o;
#Override
public void registerObserver(Observer o) {
this.o = o;
}
#Override
public void removeObserver(Observer o) {
o = null;
}
#Override
public void notifyObservers() {
o.update(data);
}
// ... other method that can update the data class
}
that is an Observer Pattern, but the way I see, you simply want to implement OnMsg100PreselectionChanged on Activity like:
public class MainActivity extends AppCompatActivity, OnMsg100PreselectionChanged {
void someMethod() {
MSG0100 msg0100 = new MSG0100();
msg0100.setOnMsgPreselectionChanged(this);
}
#Override
void onPreselectionChanged(boolean isChanged) {
}
}
I have already looked up many answers here about this issue but for the life of me I can't seem to fix this problem on my end and I need some help.
BasePresenter:
public abstract class BasePresenter<V> {
private V mView;
public void attachView(V view) { mView = view; }
public void detachView() { mView = null; }
}
BaseFragment:
public abstract class BaseFragment<P extends BasePresenter> extends Fragment {
#Inject protected P mPresenter;
#Override
public void onResume() {
super.onResume();
mPresenter.attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
}
#Override
public void onPause() {
super.onPause();
mPresenter.detachView();
}
}
MyPresenter:
public class MyPresenter extends BasePresenter<MyPresenter.MyView> {
#Inject
public MyPresenter() {}
public interface MyView {}
}
MyFragment:
public class MyFragment extends BaseFragment implements MyPresenter.MyView {}
The problem is in the type-variable declaration:
class BaseFragment<P extends BasePresenter>
BasePresenter is a generic class, so you need to specify what its type parameter is. From this snippet:
mPresenter.attachView(this);
It would seem that you expect BaseFragment to be bound to the type-variable V in BasePresenter - so I would rewrite your BaseFragment declaration as follows:
abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> { ... }
That should take care of the unchecked warning. That said, I strongly suspect that what you are really after is something like this:
abstract class BaseFragment<P extends BasePresenter<V>, V> { ... }
Where V is an independent type-variable modelling the 'view'.
Simple, instead of
public abstract class BaseFragment<P extends BasePresenter> extends Fragment {
It should be
public abstract class BaseFragment<V, P extends BasePresenter<V>> extends Fragment {
or
public abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> extends Fragment {
or
public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment {
Basically, make sure the BasePresenter is parametrized with something.
EDIT:
Okay, based on what you're actually trying to do, you should do it like this:
public abstract class BasePresenter<V> {
private V mView;
public void attachView(V view) { mView = view; }
public void detachView() { mView = null; }
}
public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment {
protected abstract P getPresenter();
#Override
public void onResume() {
super.onResume();
getPresenter().attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
}
#Override
public void onPause() {
super.onPause();
getPresenter().detachView();
}
}
public class MyPresenter extends BasePresenter<MyPresenter.MyView> {
#Inject
public MyPresenter() {}
public interface MyView {}
}
public class MyFragment extends BaseFragment<MyFragment, MyPresenter> implements MyPresenter.MyView {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyFragmentComponent component = ((MainActivity)getActivity()).getComponent().myFragmentComponent();
component.inject(this);
View view = inflater.inflate(R.layout.blah, container, false);
ButterKnife.bind(this, view);
return view;
}
}
EDIT2: Based on provided example:
public class RexTester {
// MAIN CLASS
static class Rextester {
public static void main(String args[]) {
new MyFragment();
}
}
// MVP CODE
interface BaseView {}
final static class MyPresenter extends BasePresenter<MyPresenter.MyView> {
public MyPresenter() {}
public void executeAction() {
mView.onCallback();
}
interface MyView extends BaseView {
void onCallback();
}
}
abstract static class BasePresenter<V extends BaseView> {
protected V mView;
public void attachView(V view) { mView = view;}
public void detachView() { mView = null; }
}
final static class MyFragment extends BaseFragment<MyPresenter.MyView, MyPresenter> implements MyPresenter.MyView {
private MyPresenter mPresenter;
public MyFragment() {
mPresenter = new MyPresenter();
onResume(); // Mock onResume() lifecycle event!
mPresenter.executeAction();
onPause(); // Mock onPause() lifecycle event!
}
protected MyPresenter getPresenter() {
return mPresenter;
}
#Override
protected MyPresenter.MyView getThis() {
return this;
}
public void onCallback() {
System.out.println("Hello AndroidMVP!");
}
}
abstract static class BaseFragment<V extends BaseView, P extends BasePresenter<V>> extends Fragment implements BaseView {
protected abstract P getPresenter();
protected void onResume() {
super.onResume();
getPresenter().attachView(getThis());
}
protected abstract V getThis();
protected void onPause() {
super.onPause();
getPresenter().detachView();
}
}
// ANDROID FRAMEWORK MOCK
abstract static class Fragment {
protected void onResume() {}
protected void onPause() {}
}
}
So I need to have access to a variable from MainActivty from another class. what's the best way to do so. Below is the scenario but I cannot call frag.receiveInt(give_this_int_to_fragment);
MainActivity.java:
import com.me.fragments.FragmentExtender
public class MainActivity{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
give_this_int_to_frag = new int();
frag.receiveInt(give_this_int_to_frag);
}
}
FragmentExtender.java:
public class FragmentExtender extends Fragment{
int receive_int_from_main;
public View onCreateView(...){...}
receiveInt(int_from_main){
receive_int_from_main = int_from_main;
}
}
I'm not trying to create a duplicate variable, just a pointer to that variable in MainActivity if you catch my drift.
Create getter and setter for that variable in Activity
public class MainActivity{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
}
}
public int getgive_this_int_to_fragment(){
return give_this_int_to_fragment;
}
public void getgive_this_int_to_fragment(int var){
give_this_int_to_fragment = var;
}
Now, in fragment you can use getActivity() to get activity context and then call getter
public class FragmentExtender extends Fragment{
public View onCreateView(...){
//....
int var = ((MainActivity) getActivity()).getgive_this_int_to_fragment();
}
}
The more elegant way will be to implement an interface in the Fragment and make the app inherit from it. That way you can comunicate that way.
interface FragmentInterface{
Object getMainValue();
void passValueToMain(Object obj);
}
With this code, you just have to add it to the MainActivity declaration and in the fragment constructor
public class MainActivity implements FragmentInterface{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
....
}
}
And then in the Fragment
public class FragmentExtender extends Fragment{
private FragmentInterface mInterface;
int receive_int_from_main;
public View onCreateView(...){...}
#Override
public void onAttach(Context context) {
super.onAttach(context);
setListeners(context);
}
//This is for pre Marshmallow versions
#SuppressWarnings("deprecation")
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
setListeners(activity);
}
}
private void setListeners(Object object) {
if (object instanceof FragmentInterface) {
mListener = (FragmentInterface) object;
} else {
throw new RuntimeException(object.toString()
+ " must implement FragmentInterface");
}
}
}
This will work for any fragment and any activity that implement them
I want to return a callback from a custom adapter to my fragment. However the adapter won't let me pass the reference of the Fragment implementing the interface defined in custom adapter. How can I receive callbacks from adapter to fragment?
public class MyFrag extends Fragment implements MyInterface
{
#Override
public void onCreateView()
{
MyAdapter adapter = new MyAdapter(this); // error here: How to resolve
}
#Override
public void mySignal()
{
}
}
public class MyAdapter extends RecyclerViewAdapter
{
MyInterface listener;
public MyAdapter(MyInterface listener)
{
this.listener = listener;
}
public interface MyInterface
{
public void mySignal();
}
}
Just for a clear definition and SOC you could try this instead,
public class MyFrag extends Fragment
{
#Override
public void onCreateView()
{
MyAdapter adapter = new MyAdapter(new MyInterface() {
#Override
public void mySignal()
{
//do stuff here
}
});
}
}
As I know, Fragment has this method
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
Sorry for my question! What is onCreateView() method without any params?
This way will work fine if there is not any different things more.