因此,我尝试通过代码向导航抽屉中添加一些菜单项,因此我正在进行一些测试。一切正常,除了尝试为菜单项设置图标时出现的RuntimeException
错误。该错误使我感到困惑,因为它表示在投射NavigationMenuSeperatorItem
时遇到问题。
程式码片段:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
Menu menu = navigationView.getMenu();
MenuItem it1 = menu.add(R.id.group1, 1, 2, "TEST DYNAMIC");
// it1.setIcon(R.drawable.ic_menu_camera);
因此,将
it1.setIcon
位注释掉,一切正常。菜单项放在正确的位置,完全没有问题。一旦在代码中添加setIcon
位,应用程序就会在启动时崩溃。我在这里做错什么了吗,还是发生了奇怪的事情?
完成mainActivity:
package com.example.tim.timapp;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
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.support.v7.widget.Toolbar;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.fragments.MainFragments.MainFragment;
import com.example.fragments.MainFragments.SubFragments.VariableFragment;
import com.example.fragments.MainFragments.TimeLightFragment;
import com.example.fragments.MainFragments.ToggleLightFragment;
import com.example.fragments.MainFragments.WakeUpLightFragment;
import com.example.fragments.Settings.GeneralSettingsFragment;
import com.example.fragments.Settings.StuffManagerFragment;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static boolean isMainShown = false;
private static boolean isSettingsShown = false;
private static boolean doSavePopup = false;
private static String backTitle = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isMainShown = true;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
Menu menu = navigationView.getMenu();
MenuItem it1 = menu.add(R.id.group1, 1, 2, "TEST DYNAMIC");
// it1.setIcon(R.drawable.ic_menu_camera);
FragmentManager fm = getFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
}
@Override
public void onBackPressed() {
Log.d("TEST", Boolean.toString(doSavePopup));
FragmentManager fm = getFragmentManager();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (isSettingsShown) {
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
setTitle(backTitle);
isSettingsShown = false;
} else if (!isMainShown) {
fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
setTitle("Home");
isMainShown = true;
} else if (doSavePopup) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(R.string.generalSettingsLeaving)
.setTitle("TEST")
.setCancelable(true)
.setPositiveButton(R.string.generalSettingsLeavingSave, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//TODO: Clicked Save, save.
}
})
.setNegativeButton(R.string.generalSettingsLeavingDiscard, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//TODO: Clicked Discard, discard.
}
}).create().show();
// fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
// setTitle("Home");
isMainShown = true;
doSavePopup = false;
//TODO: Tidy up here, from changing to a general doSavePopup thingy.
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
FragmentManager fm = getFragmentManager();
isMainShown = false;
isSettingsShown = true;
//TODO Change from general-settings page to specific settings page.
switch (item.getItemId()) {
case 0:
fm.beginTransaction().replace(R.id.content_frame, new GeneralSettingsFragment()).addToBackStack("backStack").commit();
backTitle = getString(R.string.settings);
setTitle(backTitle + " Settings");
return true;
case 1:
fm.beginTransaction().replace(R.id.content_frame, new GeneralSettingsFragment()).addToBackStack("backStack").commit();
backTitle = getString(R.string.navdrawer_timelight);
setTitle(backTitle + " Settings");
return true;
case 2:
fm.beginTransaction().replace(R.id.content_frame, new GeneralSettingsFragment()).addToBackStack("backStack").commit();
backTitle = getString(R.string.navdrawer_togglelight);
setTitle(backTitle + " Settings");
return true;
case 3:
fm.beginTransaction().replace(R.id.content_frame, new GeneralSettingsFragment()).addToBackStack("backStack").commit();
backTitle = getString(R.string.navdrawer_wakeuplight);
setTitle(backTitle + " Settings");
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
FragmentManager fm = getFragmentManager();
isMainShown = false;
int id = item.getItemId();
if (id == R.id.nav_wakeuplight) {
fm.beginTransaction().replace(R.id.content_frame, new WakeUpLightFragment()).commit();
setTitle(getString(R.string.navdrawer_wakeuplight));
new JSONTask().execute("http://192.168.0.120:8080/json.htm?type=command¶m=getuservariables", "WuL");
doSavePopup = true;
} else if (id == R.id.nav_togglelights) {
fm.beginTransaction().replace(R.id.content_frame, new ToggleLightFragment()).commit();
setTitle(getString(R.string.navdrawer_togglelight));
} else if (id == R.id.nav_timelight) {
fm.beginTransaction().replace(R.id.content_frame, new TimeLightFragment()).commit();
setTitle(getString(R.string.navdrawer_timelight));
} else if (id == R.id.nav_generalsettings) {
fm.beginTransaction().replace(R.id.content_frame, new GeneralSettingsFragment()).commit();
setTitle(getString(R.string.navdrawer_generalsettings));
// isGeneralSettingsShown = true;
} else if (id == R.id.nav_stuffmanager) {
fm.beginTransaction().replace(R.id.content_frame, new StuffManagerFragment()).commit();
setTitle(getString(R.string.navdrawer_stuffmanager));
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public class JSONTask extends AsyncTask<String, String, String> {
final String basicAuth = "Basic " + Base64.encodeToString("pi:pass".getBytes(), Base64.NO_WRAP);
ArrayList<String> GlobalkArray = new ArrayList<>();
ArrayList<Integer> GlobalvArray = new ArrayList<>();
@Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Authorization", basicAuth);
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder buffer = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
try {
JSONObject jsonRootObject = new JSONObject(buffer.toString());
JSONArray jsonArray = jsonRootObject.optJSONArray("result");
ArrayList<String> kArray= new ArrayList<>();
ArrayList<Integer> vArray= new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
int idx = Integer.parseInt(jsonObject.optString("idx"));
String name = jsonObject.optString("Name");
int value = Integer.parseInt(jsonObject.optString("Value"));
kArray.add(i, name);
vArray.add(i, value);
}
int j = 0;
for (int i=0; i < kArray.size(); i++){
if ((kArray.get(i)).contains(params[1])){
GlobalkArray.add(j, kArray.get(i));
GlobalvArray.add(j, vArray.get(i));
j++;
} else {
Log.d("Array", "This value (" + kArray.get(i) + ") does not contain the parameter (" + params[1] + ")");
// Do nothing, filters out all variables that do NOT have the given parameter in it.
}
}
} catch (JSONException e) {e.printStackTrace();}
return "true";
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute (String result){
super.onPostExecute(result);
FragmentManager fm = getFragmentManager();
if (result != null) {
for (int i=0; i < GlobalkArray.size(); i++) {
fm.beginTransaction().add(R.id.FragmentContainer, new VariableFragment(), "VariableFragment").commit();
fm.executePendingTransactions();
((VariableFragment)getFragmentManager().findFragmentByTag("VariableFragment")).setTextView(GlobalkArray.get(i));
((VariableFragment)getFragmentManager().findFragmentByTag("VariableFragment")).setEditText(GlobalvArray.get(i).toString());
}
} else {
Log.e("OnPostExecute", "Result is null");
}
}
}
}
日志:
02-23 13:41:59.730 13630-13630/com.example.tim.timapp I/art: Not late-enabling -Xcheck:jni (already on)
02-23 13:41:59.800 13630-13630/com.example.tim.timapp W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-2/lib/x86_64
02-23 13:41:59.960 13630-13630/com.example.tim.timapp D/AndroidRuntime: Shutting down VM
02-23 13:41:59.960 13630-13630/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.tim.timapp, PID: 13630
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}: java.lang.ClassCastException: android.support.design.internal.NavigationMenuPresenter$NavigationMenuSeparatorItem cannot be cast to android.support.design.internal.NavigationMenuPresenter$NavigationMenuTextItem
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassCastException: android.support.design.internal.NavigationMenuPresenter$NavigationMenuSeparatorItem cannot be cast to android.support.design.internal.NavigationMenuPresenter$NavigationMenuTextItem
at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.appendTransparentIconIfMissing(NavigationMenuPresenter.java:507)
at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.prepareMenuItems(NavigationMenuPresenter.java:493)
at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.update(NavigationMenuPresenter.java:426)
at android.support.design.internal.NavigationMenuPresenter.updateMenuView(NavigationMenuPresenter.java:113)
at android.support.v7.view.menu.MenuBuilder.dispatchPresenterUpdate(MenuBuilder.java:284)
at android.support.v7.view.menu.MenuBuilder.onItemsChanged(MenuBuilder.java:1030)
at android.support.v7.view.menu.MenuItemImpl.setIcon(MenuItemImpl.java:445)
at com.example.tim.timapp.MainActivity.onCreate(MainActivity.java:74)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-23 13:47:00.290 13630-13630/? I/Process: Sending signal. PID: 13630 SIG: 9
Activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:visible="true" android:orderInCategory="1" android:id="@+id/group1" >
<item android:title="TEST SOLID"/>
</group>
<item android:title="@string/navdrawer_title1" android:orderInCategory="2">
<menu>
<item
android:id="@+id/nav_wakeuplight"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/navdrawer_wakeuplight" />
<item
android:id="@+id/nav_togglelights"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/navdrawer_togglelight" />
<item
android:id="@+id/nav_timelight"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/navdrawer_timelight" />
</menu>
</item>
<item android:title="@string/navdrawer_title2" android:orderInCategory="3">
<menu>
<item
android:id="@+id/nav_generalsettings"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/navdrawer_generalsettings" />
<item
android:id="@+id/nav_stuffmanager"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/navdrawer_stuffmanager" />
</menu>
</item>
</menu>
最佳答案
我遇到了同样的错误。我在主导航菜单中使用了多个组。将ID添加到群组可以为我解决。
<group
android:id="@+id/group1"
android:checkableBehavior="single">
<item
android:id="@+id/item1"
android:icon="@android:drawable/.."
android:title="---" />
<item
android:id="@+id/item2"
android:icon="@android:drawable/.."
android:title="--" />
</group>
<group
android:id="@+id/group2"
android:checkableBehavior="single">
<item
android:id="@+id/item3"
android:icon="@android:drawable/.."
android:title="---" />
<item
android:id="@+id/item4"
android:icon="@android:drawable/.."
android:title="--" />
</group>
也许尝试将ID添加到与该组处于同一层次结构级别的项目。