如何处理另一个 activity 中的导航抽屉事件?

How to handle navigation drawer's event in another activity?

我有一个主 activity 有很多片段。我在主 activity 中实现了导航抽屉,这样当我查看片段时,我也可以打开导航抽屉。在 main_activity.xml 布局文件(参见下文)中,我使用 <include layout="@layout/navigation_drawer"/> 来包含导航抽屉的布局。在导航抽屉里,我有很多按钮和文本,可以将用户重定向到不同的片段。

目前,我正在处理主 activity 内导航抽屉的所有 onClick 事件。然而,这使得我在主 activity 中的代码非常长并且非常难以管理(就可读性和是否易于编辑而言)。如何处理另一个专门处理导航抽屉事件的 class 中的 onClick 事件?实现此目标的最佳方法是什么?

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>

MainActivityclass

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.
    }
}

创建一个实现 View.OnClickListener 接口的 class 并将新创建的 class 对象传递给小部件 setonclicklistner 方法 public class MainActivity 扩展 FragmentActivity 实现 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) {

    }
}

我建议另一种操作:MVP架构。

通过使用这种架构,您可以使用演示器将视图与逻辑分开。

目标是有更多 classes,其中包含小块代码,以便所有单元测试和维护。

这样做:

  1. 创建一个 Presenter 接口,其中包含一个 init() 方法和您需要的所有方法,在方法本身内部传递所有参数(但不是视图)
  2. 创建一个实现此接口的 PresenterImplementationclass
  3. 创建一个Activity查看界面
  4. 在您的 Activity 中实现此接口,以便在执行 PresenterImplementation 逻辑后,您可以在同一个 PresenterImplementation class 中调用视图。

这是一个基本示例,您可以对其进行修改以满足您的需要。

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);
}

}

这只是举例。

形式应该是将逻辑与视图分开。这样一切都变得更具可读性、可测试性和可维护性。

希望对您有所帮助。