具有多个活动的安卓导航抽屉



我正在尝试创建一个带有导航抽屉的 BaseActivity 并将其扩展到其他活动中,以便我可以重用导航抽屉代码。

到目前为止,我所发现的:

  • 我可以使用片段来做到这一点(我可以做到)。
  • 我可以使用 BaseActivity 并膨胀内容区域(在我的情况下,ID 为"main_container"的框架布局)以显示其他活动。在这种情况下,我已经弄清楚了如何单击导航抽屉项目来更改活动。

但是,当我的一个活动(示例活动 A)中有一个按钮,并且我想通过单击该按钮加载另一个活动(活动 B)、显示 Toast 等时,除非我在 BaseActivity 的 onCreate 方法中为侦听器编写代码,否则单击侦听器不起作用。

对我来说,这没有意义,因为它迫使我在 BaseActivity 中编写所有代码,这不是编写代码的最有效方式(活动就像片段一样,所以我只能使用片段)。

我想知道的是,如何在扩展 BaseActivity 的所有活动上加载导航抽屉,并且仍然允许活动保留其行为。

代码示例

我的activity_home.xml(基本活动)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeActivity"
tools:openDrawer="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/custom_tool"
layout="@layout/custom_bar"/>

<FrameLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/nav_display"
app:menu="@menu/nav_drawer_menu"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"/>
</android.support.v4.widget.DrawerLayout>

activity_main.xml(活动 A)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout  
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="147dp"
android:layout_marginStart="105dp"
android:layout_marginLeft="105dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="105dp"
android:layout_marginRight="105dp"
android:layout_marginBottom="48dp"
android:contentDescription="@string/app_logo"
app:layout_constraintBottom_toTopOf="@+id/search_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@mipmap/ic_launcher" />

<SearchView
android:id="@+id/search_bar"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="50dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="50dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="50dp"
android:background="@drawable/input_default"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/search_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
android:id="@+id/search_button"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="150dp"
android:layout_marginLeft="150dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="150dp"
android:layout_marginRight="150dp"
android:layout_marginBottom="228dp"
android:background="@drawable/button_default"
android:text="@string/search"
android:textColor="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar" />
</android.support.constraint.ConstraintLayout>

当应用程序最初加载时,基本活动的"main_content"会随着activity_main布局而膨胀。

当我单击activity_main.xml内的search_button时,我想加载另一个活动,该活动仅在我在基本活动中编写代码时发生。

主页活动

package com.example.naisse;

import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
public class HomeActivity extends AppCompatActivity {
protected static int position;
private DrawerLayout drawer;
protected FrameLayout frames;
Button searchButton;
/**
*  This flag is used just to check that launcher activity is called first time
*  so that we can open appropriate Activity on launch and make list item position selected accordingly.
* */
private static boolean isLaunch = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = findViewById(R.id.custom_tool);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
frames = findViewById(R.id.main_container);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();

/*inflating the layout with activity_main*/
getLayoutInflater().inflate(R.layout.activity_main, frames);

searchButton = findViewById(R.id.search_button);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*removing the activity_main and inflating they layout with activity_result*/
frames.removeAllViews();
getLayoutInflater().inflate(R.layout.activity_result, frames);
}
});
}
@Override
public void onBackPressed() {
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
super.onBackPressed();
}
}
}

使用家庭活动扩展主活动

主活动

package com.example.naisse;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends HomeActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

}
}

如何解决这个问题?

我很惊讶这些年来很少有人有兴趣这样做。 在所有活动的xml文件中维护DrawerLayout内容的重复代码是非常愚蠢的。

我尝试了@Mill3r的自我答案,不幸的是覆盖setContentView与数据绑定冲突并导致崩溃。

我没有在 setContentView 中创建一个基本活动的方法,如下所示:

public void setContent(View contentView) {
// Find the content container
frames = findViewById(R.id.main_container);
frames.removeAllViews();
frames.addView(contentView);
// The rest of the base setup
Toolbar toolbar = findViewById(R.id.custom_tool);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}

然后在从 base 嘲笑的所有活动中,在设置数据绑定后调用此函数,例如:

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
setContent(binding.getRoot());

为了回答和理解,请阅读我和迈克·

我最初所做的是用布局膨胀"main_container",因此 Activity 类没有被触发。为此,我必须在 BaseActivity (在我的例子中为 HomeActivity)中重写setContentView()方法,并将每个可共享的代码(如工具栏和导航抽屉)放入其中。

我的新家活动.class

public class HomeActivity extends AppCompatActivity {
private DrawerLayout drawer;
protected FrameLayout frames;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
@Override
public void onBackPressed() {
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
super.onBackPressed();
}
}

@Override
public void setContentView(int layoutResID) {
// Set the base layout
super.setContentView(R.layout.activity_home);
// Find the content container
frames = findViewById(R.id.main_container);
// Inflate the extending Activity's layout into it
getLayoutInflater().inflate(layoutResID, frames);
// The rest of the base setup
Toolbar toolbar = findViewById(R.id.custom_tool);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
}

现在,工具栏和导航抽屉在所有活动中共享。

相关内容

  • 没有找到相关文章

最新更新