Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

combine Fragment and Activity class in Base class

I have 2 classes:

public class MyFragment extends Fragment implements MyListener
public void myFun1()
public void myFun2()
public void myFun23()

public class MyActivity extends AppCompatActivity implements MyListener
public void myFun1()
public void myFun2()
public void myFun34()

I am trying to combine my two classes in an base class so I need to write myFun1() and myFun2() only once but the problem is that one class extends Fragment and one class extends Activity. How can I bring the functions together in one base class?

EDIT: The methods do not come from the listener and can be ignored. myFun1() and myFun2() have the same functionality while myFun23() and myFun34() have both a special function only necessary in its class

like image 799
rm -rf Avatar asked Aug 14 '19 06:08

rm -rf


People also ask

Can you start an activity from a fragment?

If you want to start a new instance of mFragmentFavorite , you can do so via an Intent . Intent intent = new Intent(this, mFragmentFavorite. class); startActivity(intent); If you want to start aFavorite instead of mFragmentFavorite then you only need to change out their names in the created Intent .

Can a fragment be used in multiple activities?

You can use multiple instances of the same fragment class within the same activity, in multiple activities, or even as a child of another fragment. With this in mind, you should only provide a fragment with the logic necessary to manage its own UI.

What is the base class of activity class?

Context is the base class for Activity.

Can a fragment without a layout can be attached to an activity?

A fragment is not required to be a part of the Activity layout ; you may also use a fragment without its own UI as an invisible worker for the Activity but it needs to be attached to an Activity in order to appear on the screen.


Video Answer


2 Answers

You can do it only with Java8 that introduced the default methods in interfaces.
You can define something like:

public interface MyInterface {

    default void myFun1() {
         // default method implementation
    }

    default void myFun2() {
         // default method implementation
    }

}

Then:

   public class MyActivity extends AppCompatActivity implements MyListener, MyInterface {

     // Just define
     public void myFun23(){}
   }

   public class MyFragment extends Fragment implements MyListener, MyInterface {

     // Just define
     public void myFun34(){}
   }

You can do the same with kotlin.

interface MyInterface {
    fun myFun1() {
      // implementation
    }
    //...
}

Then:

class MainActivity : AppCompatActivity(), MyInterface {

    fun func23() {
       //...
    }
}

....
like image 69
Gabriele Mariotti Avatar answered Oct 14 '22 06:10

Gabriele Mariotti


In this specific situation probably your myFun1() and myFun2() access some member variables in MyFragment and MyActivity. If you want to common out (like strategy pattern) the implementation of the myFun1() and myFun2() you should supply those variables to the common implementation either directly, or indirectly by introducing another interface.

The second solution of introducing another interface is mostly not preferable. In the first solution we end up with a strategy like the following.

class DataFetchingStrategy(val repo: Repository) : MyListener {
    fun myFun1() {
      repo.fetchData1()
    }

    fun myFun2() {
      repo.fetchData2()
    }
}

A strategy is not a listener. Even though we name it differently like DataFetcher or RepoManager, they are also not listeners.

Then how can we eliminate the duplicate code from the listener methods? Listener methods should be as lean as possible and the listener implementations should be ad hoc. The listener methods will forward the call to a strategy or delegate or composite etc. Not the strategy or delegate or composite will implement the listener.

class DataFetcher(val repo: Repository) {
  fun fetchData1() {
    // implementation
  }

  fun fetchData2() {
    // implementation
  }
}

class MyFragment : Fragment, MyListener {
  val dataFetcher = DataFetcher(Repository())

  fun myFun1() = dataFetcher.fetchData1()

  fun myFun2() = dataFetcher.fetchData2()

  fun myFun23() {}
}

class MyActivity : AppCompatActivity, MyListener {
  val dataFetcher = DataFetcher(Repository())

  fun myFun1() = dataFetcher.fetchData1()

  fun myFun2() = dataFetcher.fetchData2()

  fun myFun34() {}
}
like image 22
Durgadass S Avatar answered Oct 14 '22 06:10

Durgadass S