在充气新视图元素时Android应用程序崩溃

时间:2013-08-07 06:07:38

标签: android xml layout user-interface inflate


预期结果:

Android版本= 2.2

使用inflate()RelativeLayout编程方式在LinearLayout中添加main_menu.xmlitem_list。线性布局(main_menu.xml中的ID为RelativeLayout relativeLayout = (RelativeLayout) RelativeLayout.inflate(MainActivity.this, R.layout.template_item_list_cell, linearLayoutItemList); )是用于保存项目列表的容器。每个项目都是相对布局,并将在从服务器接收数据后以编程方式添加回调函数。

inflate()的使用是从here学习的。


问题:

在此语句中运行时应用程序崩溃(错误消息中为MainActivity.java:693),

updateItemList()

但是,如果以下RelativeLayout relativeLayout = new RelativeLayout(MainActivity.this); RelativeLayout.LayoutParams relativeLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, height); relativeLayout.setLayoutParams(relativeLayoutParams); relativeLayout.setBackgroundResource(R.color.cell_state); relativeLayout.setClickable(true); 中的上述语句被以下内容替换,那么该应用效果很好,

linearLayoutItemList.addView(relativeLayout);

并插入此声明,

// Add the RelativeLayout to LinearLayout

评论后,

08-07 13:54:44.689: W/dalvikvm(23363): threadid=1: thread exiting with uncaught exception (group=0x4001e578)
08-07 13:54:44.699: E/AndroidRuntime(23363): FATAL EXCEPTION: main
08-07 13:54:44.699: E/AndroidRuntime(23363): java.lang.ClassCastException: android.widget.LinearLayout
08-07 13:54:44.699: E/AndroidRuntime(23363):    at com.domainname.appname.android.MainAc$12$1.run(MainActivity.java:693)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at android.os.Handler.handleCallback(Handler.java:587)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at android.os.Looper.loop(Looper.java:130)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at android.app.ActivityThread.main(ActivityThread.java:3691)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at java.lang.reflect.Method.invokeNative(Native Method)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at java.lang.reflect.Method.invoke(Method.java:507)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
08-07 13:54:44.699: E/AndroidRuntime(23363):    at dalvik.system.NativeStart.main(Native Method)

错误消息:

res/layout/main_menu.xml

代码

<?xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item_list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#555555" android:orientation="vertical" > </LinearLayout>

res/layout/template_item_list_cell.xml

<?xml version="1.0" encoding="utf-8"? > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="41dp" android:background="@color/cell_state" android:clickable="true" android:visibility="gone" > </RelativeLayout>

res/color/cell_state.xml

<?xml version="1.0" encoding="utf-8"? > <selector xmlns:android="http://schemas.android.com/apk/res/android" > <!-- Active state --> <item android:state_selected="true" android:state_focused="false" android:state_pressed="false" android:drawable="@color/MyDarkGray" /> <!-- Inactive state--> <item android:state_selected="false" android:state_focused="false" android:state_pressed="false" android:drawable="@color/MyGray" /> <!-- Pressed state--> <item android:state_pressed="true" android:drawable="@color/MyDarkGray" /> <!-- Selected state (using d-pad) --> <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@color/MyDarkGray" /> </selector>

res/values/customized_colors.xml

<?xml version="1.0" encoding="utf-8"? > <resources> <color name="MyGray">#555555</color> <color name="MyDarkGray">#333333</color> </resources>

src/com.domainname.appname.android/MainActivity.java

public class MainActivity extends Activity { @Override public void onCreate{ // Some initialization setContentView(R.layout.main_menu); // Some other initialization } public void updateItemList() { // Remove previous items in the list LinearLayout linearLayoutItemList = (LinearLayout) menu.findViewById(R.id.item_list); // The linear layout is given an ID of item_list in main_menu.xml linearLayoutItemList.removeAllViews(); // Request to server and define the callback function to add item(s) to the list programmatically JSONObject json = new JSONObject(); MyRequestClass request = new MyRequestClass(); request.request(MyConstants.WEB_BASE_URL, "app/get_latest_item_list", json, new MyCallbackClass() { @Override public void run(final JSONObject json) { runOnUiThread(new Runnable() { @Override public void run() { try { String jsonInString = json.toString(); JSONArray jsonArray = json.getJSONArray("data"); // Suppose the JSON is properly returned int numberOfItemListItems = jsonArray.length(); RelativeLayout relativeLayoutItemListTitleBar = (RelativeLayout) menu.findViewById(R.id.item_list_title_bar); View viewDivider1 = (View) menu.findViewById(R.id.item_list_divider_1); View viewDivider2 = (View) menu.findViewById(R.id.item_list_divider_2); LinearLayout linearLayoutItemList = (LinearLayout) menu.findViewById(R.id.item_list); View viewDivider3 = (View) menu.findViewById(R.id.item_list_divider_3); View viewDivider4 = (View) menu.findViewById(R.id.item_list_divider_4); if (0 == numberOfItemListItems) { relativeLayoutItemListTitleBar.setVisibility(RelativeLayout.GONE); viewDivider1.setVisibility(View.GONE); viewDivider2.setVisibility(View.GONE); linearLayoutItemList.setVisibility(LinearLayout.GONE); viewDivider3.setVisibility(View.GONE); viewDivider4.setVisibility(View.GONE); } else { relativeLayoutItemListTitleBar.setVisibility(RelativeLayout.VISIBLE); viewDivider1.setVisibility(View.VISIBLE); viewDivider2.setVisibility(View.VISIBLE); linearLayoutItemList.setVisibility(LinearLayout.VISIBLE); viewDivider3.setVisibility(View.VISIBLE); viewDivider4.setVisibility(View.VISIBLE); for (int index = 0; index < numberOfItemListItems; index++) { try { JSONObject currentJsonObject = jsonArray.getJSONObject(index); // Extract item title String currentTitle = currentJsonObject.getString("Title"); // Extract icon image URI final String currentIconImageUri = ITEM_ICON_IMAGE_BASE_URL + currentJsonObject.getString("IconImageUri"); // Extract item ID final String currentItemId = currentJsonObject.getString("ItemIdUri"); // Create a cell to display the item linearLayoutItemList = (LinearLayout) menu.findViewById(R.id.item_list); // Create RelativeLayout for the cell int height = (int) (getResources().getDisplayMetrics().density * 41 + 0.5f); // 41dp height RelativeLayout relativeLayout = (RelativeLayout) LinearLayout.inflate(linearLayoutItemList.getContext(), R.layout.template_item_list_cell, linearLayoutItemList); relativeLayout.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ selectItemListCell(currentItemId); } }); // Add icon image to a ImageView and add that TextView to RelativeLayout ImageView imageView = new ImageView(MainActivity.this); imageView = loadImageWithUrlString(imageView, currentIconImageUri); int width = (int) (getResources().getDisplayMetrics().density * 31 + 0.5f); // 31dp height height = (int) (getResources().getDisplayMetrics().density * 31 + 0.5f); // 31dp height RelativeLayout.LayoutParams relativeLayoutParams1 = new RelativeLayout.LayoutParams(width, height); relativeLayoutParams1.addRule(RelativeLayout.CENTER_VERTICAL); relativeLayoutParams1.addRule(RelativeLayout.ALIGN_PARENT_LEFT); int marginLeft = (int) (getResources().getDisplayMetrics().density * 10 + 0.5f); // 10dp int marginTop = (int) (getResources().getDisplayMetrics().density * 5 + 0.5f); // 5dp int marginRight = (int) (getResources().getDisplayMetrics().density * 0 + 0.5f); // 0dp int marginBottom = (int) (getResources().getDisplayMetrics().density * 5 + 0.5f); // 5dp relativeLayoutParams1.setMargins(marginLeft, marginTop, 0, marginBottom); imageView.setLayoutParams(relativeLayoutParams1); relativeLayout.addView(imageView); // Add title text to a TextView and add that TextView to RelativeLayout TextView textView = new TextView(MainActivity.this); textView.setText(currentTitle); float shadowRadius = 2.0f; int shadowDx = 0; int shadowDy = 1; int shadowColor = 0xFF000000; textView.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor); RelativeLayout.LayoutParams relativeLayoutParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); relativeLayoutParams2.addRule(RelativeLayout.CENTER_VERTICAL); marginLeft = (int) (getResources().getDisplayMetrics().density * 56 + 0.5f); // 56dp marginRight = (int) (getResources().getDisplayMetrics().density * 43 + 0.5f); // 43dp relativeLayoutParams2.setMargins(marginLeft, 0, marginRight, 0); textView.setLayoutParams(relativeLayoutParams2); relativeLayout.addView(textView); // Add the RelativeLayout to LinearLayout // linearLayoutItemList.addView(relativeLayout); // Add divider to the LinearLayout if (index < (numberOfItemListItems - 1)) { View view1 = new View(MainActivity.this); height = (int) (getResources().getDisplayMetrics().density * 0.5 + 0.5f); // 0.5dp height RelativeLayout.LayoutParams relativeLayoutParams3 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, height); view1.setLayoutParams(relativeLayoutParams3); view1.setBackgroundColor(0xFF323232); linearLayoutItemList.addView(view1); View view2 = new View(MainActivity.this); height = (int) (getResources().getDisplayMetrics().density * 0.5 + 0.5f); // 0.5dp height RelativeLayout.LayoutParams relativeLayoutParams4 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, height); view2.setLayoutParams(relativeLayoutParams4); view2.setBackgroundColor(0xFF595959); linearLayoutItemList.addView(view2); } } catch (JSONException e) { // Oops } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } catch (JSONException e) { e.printStackTrace(); } } }); // End of runOnUiThread() } }); } // End of updateItemList } // End of MainActivity

{{1}}

2 个答案:

答案 0 :(得分:2)

错误表示您有ClassCastException,这意味着您没有正确地投射课程。当涉及布局参数和使用的布局之间的关系时,大多数人似乎都有问题。

以下是它应该如何:

您应该为布局指定父类型的布局参数。例如,假设你有这个

Button inside a LinearLayout

如果要将LayoutParams设置为button,则必须将其设置为LinearLayout.LayoutParams类型,即父级ViewGroup按钮(每个布局基本上是一个ViewGroup - LinearLayout ,RelativeLayout等。)

在您的情况下,LayoutParams应为LinearLayout类型。其他一切都还可以。

答案 1 :(得分:1)


解决方法

更改错误的陈述,

RelativeLayout relativeLayout = (RelativeLayout) RelativeLayout.inflate(MainActivity.this, R.layout.template_item_list_cell, linearLayoutItemList);

RelativeLayout relativeLayout = (RelativeLayout) RelativeLayout.inflate(MainActivity.this, R.layout.template_item_list_cell, null);
linearLayoutItemList.addView(relativeLayout);

RelativeLayout relativeLayout = (RelativeLayout) MainActivity.this.getLayoutInflater().inflate(R.layout.template_item_list_cell, null);
linearLayoutItemList.addView(relativeLayout);

更新

但是,由于null参数中的ViewGroup root值,上述两种信息无法保留布局参数信息。

所以更好的解决方案是根据Luksprog帖子中this的答案指出正确的布局参数信息

RelativeLayout relativeLayout = (RelativeLayout) MainActivity.this.getLayoutInflater().inflate(R.layout.template_item_list_cell, (LinearLayout) linearLayoutClubList, false);
linearLayoutItemList.addView(relativeLayout);