Reputation: 558
I have a main activity with a lot of fragments. I have implemented the navigation drawer inside the main activity so that when I am viewing the fragments, I can open the navigation drawer as well. Inside the main_activity.xml
layout file (refer below), I have used <include layout="@layout/navigation_drawer"/>
to include the layout of the navigation drawer. Inside the navigation drawer, I have a lot of buttons and texts that redirect the user to different fragments.
Currently, I am handling all the onClick events of the navigation drawer inside the main activity. However, this makes my code inside the main activity very long and very hard to manage (in terms of readability and whether it is easy to edit). How to handle the onClick events in another class that specializes in handling the navigation drawer's event? What is the best way to achieve this?
main_activity.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer"
android:layout_height="match_parent"
android:layout_width="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<LinearLayout
android:id="@+id/drawerContent"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<include layout="@layout/navigation_drawer"/>
</Linear Layout>
</android.support.v4.widget.DrawerLayout>
MainActivity class
public class MainActivity extends FragmentActivity implements View.OnClickListener, DrawerLayout.DrawerListener {
Button button1;
TextView text1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
button1 = (Button)findViewById(R.id.button1);
text1 = (TextView)findViewById(R.id.text1);
button1.setOnClickListener(this);
text1.setOnClickListener(this);
}
public void onClick(View v){
//I handle all onClick events of navigation drawer here.
//I want to move all of these to another class.
//If possible, I would like to move the onClick method and declaration of Button and TextView variables too.
}
}
Upvotes: 0
Views: 1262
Reputation: 97
I suggest another operation: MVP architecture.
By using this kind of architecture you separate views from logics using a presenter.
The goal is to have more classes which contain small pieces of code so that's all unit testable and maintenable too.
Act this way:
Here's a basic example, you can modify it to fit your needs.
MyActivityPresenter.java
public interface MyActivityPresenter {
void init();
/**
* This method is for example only
* @param intent You can pass whatever you want as argument, but don't pass views
* because It would be formally uncorrect
*/
void onTextViewClicked(Intent intent);
}
MyActivityPresenterImpl.java
public class MyActivityPresenterImpl implements MyActivityPresenter {
private Activity activity;
private MyActivityPresenterView view;
public MyActivityPresenterImpl(Activity activity, MyActivityPresenterView view) {
this.activity = activity;
this.view = view;
}
@Override
public void init() {
//if(some condition or nothing at all){
view.initViews();
//}
}
@Override
public void onTextViewClicked(Intent intent) {
//Do controls in Presenter Implementation
if(intent != null){
Fragment fragment = new SomeFragment();
Bundle bundle = intent.getExtras();
if(bundle != null){
fragment.setArguments(bundle);
}
view.loadFragment(fragment);
}
}
}
MyAppBaseView.java
public interface MyAppBaseView {
//Just created in order to be extended from every interface and to not rewrite everytime from scratch each method
void loadFragment(Fragment fragment);
}
MyActivityView.java
public interface MyActivityView extends MyAppBaseView {
void initViews();
}
MyActivity.java
public class MyActivity extends AppCompatActivity implements View.OnClickListener,MyActivityView {
private TextView textView;
private Intent intent;
private MyActivityPresenter presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.something);
presenter = new MyActivityPresenterImpl(this,this);
presenter.init();
this.intent = getIntent();
}
@Override
public void initViews() {
textView = findViewById(R.id.text_view_title);
textView.setOnClickListener(this);
}
@Override
public void loadFragment(Fragment fragment) {
//Transaction
}
@Override
public void onClick(View v) {
presenter.onTextViewClicked(intent);
}
}
This is only for example.
Forma mentis should be to separate logic from views. So that all gets more readable, testable and maintainable.
Hope it helps.
Upvotes: 0
Reputation: 174
Create a class which implement View.OnClickListener interface and pass newly created class object to widget setonclicklistner method public class MainActivity extends FragmentActivity implements View.OnClickListener, DrawerLayout.DrawerListener {
Button button1;
TextView text1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
button1 = (Button)findViewById(R.id.button1);
text1 = (TextView)findViewById(R.id.text1);
button1.setOnClickListener(new ClickHander());
}}
public class ClickHander implements View.OnClickListener
{
@Override
public void onClick(View v) {
}
}
Upvotes: 1