【发布时间】:2026-02-10 12:00:01
【问题描述】:
背景:
我有一个使用 DrawerLayout 的 FragmentActivity。我创建了一个名为 NavDrawerManager 的类来抽象出处理抽屉布局的代码。要构造这个对象,我需要传入并保留对 Activity 的引用。我使用此活动引用来调用 findViewById(),并且在创建列表适配器等时也将活动用作上下文。我在活动中保留对 NavDrawerManager 对象的引用,以便我可以对抽屉布局执行回调和操作.
更新:根据 Xaver 的建议,我转而将 FragmentActivity 扩展为 NavDrawerActivity。超类处理导航抽屉代码,而不是在我的活动中使用 NavDrawerManager 对象。查看更新的代码。
问题:
在我改变方向之前一切正常。更改方向后,我的 NavDrawerActivity 似乎仍然引用旧布局。我这样说是因为我在 DrawerLayout 中有一个进度条和几个按钮,我正在尝试更新它们,但它们并不反映更新。
当我调用 Activity.findViewById() 来获取进度条并使其可见时,它不会显示任何更改,也不会显示对按钮的任何更改。注意:Activity.findViewById() 不返回 null。但是,如果我在改变方向之前做同样的事情,进度条和按钮会显示相应的变化。
代码:
NavDrawerActivity:
public class NavDrawerActivity extends LowProfileFragmentActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private ExpandableListView mDrawerList;
private NavDrawerAdapter mListAdapter;
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
mDrawerToggle.onOptionsItemSelected(item);
return super.onOptionsItemSelected(item);
}
//Called via subclass after setContentView
protected void setupNavDrawer() {
initDrawerLayout();
initDrawerList();
setButton1();
setButton2();
}
private void initDrawerLayout() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = getActionBarDrawerToggle();
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void initDrawerList() {
mDrawerList = (ExpandableListView) mDrawerLayout
.findViewById(android.R.id.list);
mListAdapter = getNavDrawerAdapter();
}
private ActionBarDrawerToggle getActionBarDrawerToggle() {
return new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_navigation_drawer, 0, 0) {
public void onDrawerClosed(View view) {
}
public void onDrawerOpened(View view) {
}
};
}
public void setDrawerLoading(boolean loading) {
ProgressBar progressBar = (ProgressBar) mDrawerLayout
.findViewById(R.id.progress_bar);
Button button1 = (Button) this.findViewById(R.id.button1);
Button button2 = (Button) this
.findViewById(R.id.button2);
/* None of the below changes appear after changing orientation */
if (loading) {
button1.setEnabled(false);
button2.setEnabled(false);
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
button1.setEnabled(true);
button2.setEnabled(true);
}
}
private void setButton1() {
Button button1 = (Button) this.findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do something
}
});
}
private void setButton2() {
Button button2 = (Button) this
.findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do something
}
});
}
}
示例活动:
public class ExampleActivity extends NavDrawerActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initUI();
}
private void initUI() {
setContentView(R.layout.activity_sift);
// Call the superclass method to set up the nav drawer
setupNavDrawer();
}
}
AndroidManifest.xml:
<activity
android:name="com.example.app.ExampleActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/AppTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
【问题讨论】:
-
如果您实现
NavDrawerActivity而不是NavDrawerManager不是更容易吗?一般来说,应该避免这样的事情。 UI 应该由Fragments或Activities自己处理。 -
这可行。我想我的活动层次结构已经变得相当广泛......我有一个 BaseFragmentActivity > LowProfileFragmentActivity > 然后是这个活动。 (代码中未显示,因为它已被剥离)。我认为制作 LowProfileNavDrawerActivity 有点过头了。
-
不,如果你创建一个专用的
NavDrawerActivity你应该没问题。 -
但问题是,我想要一个超类 Activity 来处理使系统 UI 变得“低调”(隐藏通知栏等)。如果我创建一个专用的 NavDrawerActivity,我不能从 LowProfileFragmentActivity 扩展,因为它似乎违反了某种形式的 SRP 对我来说......可能是完全错误的。
-
不,如果不允许您重用已经存在的实现,那将破坏抽象的目的。很多抽象是很棒的,但是当它过度时,它可能会成为一个问题。不要过分关注完全抽象并符合 OOP 标准的所有内容。
Activity同时拥有NavigationDrawer并隐藏通知栏并没有错。如果你已经有一个Activity实现了这两件事之一,你应该扩展它。您唯一的其他选择是在第二个Activity中重新实现相同的行为。
标签: android android-activity android-orientation android-context android-side-navigation