我创建了一个包含自定义Toolbar
和NavigationDrawer
的Android应用。我使用Android API 22并在Nexus 5(Android 5.1.0)上进行了测试。当我在横向屏幕中启动应用程序(并且还将应用程序从纵向旋转到横向)时,应用程序始终显示无限闪烁。虽然,我旋转到肖像,它仍然闪烁。我运行调试器,发现Activity.onCreate
总是被重复调用。
这是我的代码:
的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/MyTheme.NoActionBar">
<activity
android:name=".activity.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.SettingsActivity"
android:configChanges="locale"
android:label="@string/settings"
android:parentActivityName=".activity.MainActivity"
android:theme="@style/MyTheme.Light">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.MainActivity" />
</activity>
</application>
</manifest>
MainActivity.java
package com.example.activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import com.example.R;
import com.example.nav.NavDrawerItem;
import com.example.nav.NavDrawerListAdapter;
import com.example.util.VersionUtil;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
private Toolbar mToolbar;
private DrawerLayout mDrawerLayout;
private LinearLayout mDrawerRoot;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private NavDrawerListAdapter mDrawerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.main_drawer_layout);
mDrawerRoot = (LinearLayout) findViewById(R.id.drawer_root);
initNavigationDrawer();
}
protected void initNavigationDrawer() {
if (mToolbar != null) {
setSupportActionBar(mToolbar);
}
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
String[] navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
TypedArray navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
TypedArray navMenuSelectedIcons = getResources().obtainTypedArray(R.array.nav_drawer_selected_icons);
ArrayList<NavDrawerItem> navDrawerItems = new ArrayList<>();
for (int i = 0, len = navMenuTitles.length; i < len; i++) {
navDrawerItems.add(new NavDrawerItem(navMenuTitles[i], navMenuIcons.getResourceId(i, -1), navMenuSelectedIcons.getResourceId(i, -1), false));
}
// Recycle the typed array
navMenuIcons.recycle();
navMenuSelectedIcons.recycle();
// setting the nav drawer list adapter
mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext(), navDrawerItems);
mDrawerList.setAdapter(mDrawerAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDrawerList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
selectDrawerMenuItem(0);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void setTitle(CharSequence title) {
if (mToolbar != null) {
mToolbar.setTitle(title);
} else {
super.setTitle(title);
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectDrawerMenuItem(position);
}
}
private void selectDrawerMenuItem(int position) {
switch (position) {
case 3: // Settings
showSettings();
break;
case 4: // Help and Feedback
sendHelpAndFeedbackEmail();
break;
default:
setSelectedNavItemMenu(position);
break;
}
mDrawerLayout.closeDrawer(mDrawerRoot);
}
private void setSelectedNavItemMenu(int position) {
for (int i = 0, size = mDrawerAdapter.getCount(); i < size; i++) {
NavDrawerItem menuItem = (NavDrawerItem) mDrawerAdapter.getItem(i);
menuItem.setSelected(i == position);
}
mDrawerList.setItemChecked(position, true);
}
private void showSettings() {
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
}
private void sendHelpAndFeedbackEmail() {
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setType("text/plain");
String versionName = VersionUtil.getVersionName(this);
int versionCode = VersionUtil.getVersionCode(this);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(getString(R.string.email_help_subject), getText(R.string.app_name), versionName, versionCode));
emailIntent.setData(Uri.parse("mailto:" + getText(R.string.email_send_to)));
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(emailIntent, getText(R.string.email_chooser_title)));
}
}
为什么应用程序会闪烁?有没有解决这个问题的方法? 感谢。
编辑#1
这是来自Logcat:
...
03-22 22:50:51.716 31125-31125/com.example W/View﹕ requestLayout() improperly called by android.widget.ListView{654f6b5 VFED.VC. ......ID 0,75-912,1080 #7f0b0042 app:id/drawer_list} during layout: running second layout pass
03-22 22:50:51.821 31125-31125/com.example W/View﹕ requestLayout() improperly called by android.widget.ListView{3df1b0fa VFED.VC. ......ID 0,75-912,1080 #7f0b0042 app:id/drawer_list} during layout: running second layout pass
03-22 22:50:51.918 31125-31125/com.example W/View﹕ requestLayout() improperly called by android.widget.ListView{7b0a09b VFED.VC. ......ID 0,75-912,1080 #7f0b0042 app:id/drawer_list} during layout: running second layout pass
...
重复了这些错误。
编辑#2
activity_main.xml中
<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/main_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Your normal content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- We use a Toolbar so that our drawer can be displayed
in front of the action bar -->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<!-- The rest of your content view -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Activity Content"
android:textColor="#000" />
</RelativeLayout>
</LinearLayout>
<!-- Your drawer view. This can be any view, LinearLayout
is just an example. As we have set fitSystemWindows=true
this will be displayed under the status bar. -->
<LinearLayout
android:id="@+id/drawer_root"
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="true">
<!-- Your drawer content -->
<ListView
android:id="@+id/drawer_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:divider="@null"
android:fastScrollEnabled="false"
/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
编辑#3
NavDrawerListAdapter.java
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.R;
/**
* Created by edward on 01/03/2015.
*/
public class NavDrawerListAdapter extends BaseAdapter {
private Context context;
private ArrayList<NavDrawerItem> navDrawerItems;
public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems) {
this.context = context;
this.navDrawerItems = navDrawerItems;
}
@Override
public int getCount() {
return navDrawerItems.size();
}
@Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.nav_list_item, null);
}
ImageView imgIcon = (ImageView) convertView.findViewById(R.id.nav_icon);
TextView txtTitle = (TextView) convertView.findViewById(R.id.nav_title);
TextView txtCount = (TextView) convertView.findViewById(R.id.nav_counter);
NavDrawerItem item = navDrawerItems.get(position);
if (item.isSelected()) {
imgIcon.setImageResource(navDrawerItems.get(position).getIconSelectedResId());
} else {
imgIcon.setImageResource(navDrawerItems.get(position).getIconResId());
}
txtTitle.setText(item.getTitle());
if (navDrawerItems.get(position).isCounterVisible()) {
txtCount.setVisibility(View.VISIBLE);
txtCount.setText(navDrawerItems.get(position).getCount());
} else {
txtCount.setVisibility(View.GONE);
}
return convertView;
}
}
nav_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/nav_background_selector"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
<ImageView
android:id="@+id/nav_icon"
android:layout_width="@dimen/nav_icon_size"
android:layout_height="@dimen/nav_icon_size"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_marginRight="24dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/nav_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/nav_icon"
android:gravity="center_vertical"
android:paddingRight="40dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/primary_text"
android:textStyle="bold"/>
<TextView
android:id="@+id/nav_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:background="@color/primary_light"
android:text="0"
android:textColor="@color/primary_text" />
</RelativeLayout>
答案 0 :(得分:2)
从setContentView(R.layout.activity_main);
方法
onConfigurationChanged()
如果您使用此功能,请将其删除
android:fastScrollEnabled="true"
android:fastScrollAlwaysVisible="true"