Android方向改变崩溃

时间:2013-10-10 10:38:03

标签: java android xml android-layout android-custom-view

我在TextView编写了自定义视图,其中包含EditTextLinearLayout

但是在Orientation Change我得到了错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{ge.altasoft.datacollector/ge.altasoft.datacollector.ViewPagerActivity}: java.lang.ClassCastException: android.widget.TextView$SavedState cannot be cast to android.widget.AbsSpinner$SavedState
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2122)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3550)
    at android.app.ActivityThread.access$700(ActivityThread.java:140)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4895)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.ClassCastException: android.widget.TextView$SavedState cannot be cast to android.widget.AbsSpinner$SavedState
    at android.widget.AbsSpinner.onRestoreInstanceState(AbsSpinner.java:426)
    at android.view.View.dispatchRestoreInstanceState(View.java:12217)
    at android.view.ViewGroup.dispatchThawSelfOnly(ViewGroup.java:2613)
    at android.widget.AdapterView.dispatchRestoreInstanceState(AdapterView.java:790)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2599)
    at android.view.View.restoreHierarchyState(View.java:12195)
    at android.support.v4.app.Fragment.restoreViewState(Fragment.java:417)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:933)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1178)
    at android.app.Activity.performStart(Activity.java:5173)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2070)
    ... 12 more

这是我的代码:

XEditText 类:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Parcelable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.StringTokenizer;
import ge.altasoft.datacollector.R;

/**
 * .
 */

public class XEditText extends LinearLayout {
    private LayoutInflater inflater;
    private View view;
    private TextView label;
    private EditText edit;
    private String viewParameter, textLabel;
    private int dafarvisTarigiId = -1, gacemisTarigiId = -1;
    private boolean xTextChanged = true;

public XEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    initViews();
    getViewAttributes(context, attrs);
    addListeners();
}

public String getXViewParameter(){
    return String.valueOf(this.viewParameter);
}

public String getXValue(){
    return String.valueOf(this.edit.getText());
}

public void setXValue(String xValue) {
    this.edit.setText(String.valueOf(xValue));
}

public void setXTextChanged (boolean ch) {
    this.xTextChanged = ch;
}

private void initViews(){
    inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = inflater.inflate(R.layout.x_edittext_view, this, true);
    label = (TextView) findViewById(R.id.label);
    edit = (EditText) findViewById(R.id.input);
}

/**
 * Getting all attributes of view Id-s.
 *
 * @param context
 * @param attrs
 */
private void getViewAttributes(Context context, AttributeSet attrs) {
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XEditText);
    final int N = a.getIndexCount();
    for(int i = 0; i < N; i++){
        int attr = a.getIndex(i);
        switch(attr){
            case R.styleable.XEditText_textLabel:
                textLabel = a.getString(attr);
                label.setText(String.valueOf(textLabel));
                break;
            case R.styleable.XEditText_viewParameter:
                viewParameter = a.getString(attr);
                break;
            case R.styleable.XEditText_dafarvisTarigi:
                dafarvisTarigiId = a.getResourceId(attr, -1);
                break;
            case R.styleable.XEditText_gacemisTarigi:
                gacemisTarigiId = a.getResourceId(attr, -1);
                break;
            case R.styleable.XEditText_android_inputType:
                int inputType = a.getInt(attr, EditorInfo.TYPE_TEXT_VARIATION_NORMAL);
                edit.setInputType(inputType);
                break;
        }
    }
    a.recycle();
}

private void addListeners() {
    this.edit.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                ((LinearLayout) v.getParent()).setBackgroundColor(Color.LTGRAY);
            } else {
                ((LinearLayout) v.getParent()).setBackgroundColor(Color.TRANSPARENT);
            }
        }
    });
    if(gacemisTarigiId != -1 && dafarvisTarigiId != -1){
        Watcher watch = new Watcher(this);
        this.edit.addTextChangedListener(watch);
    }else
        return;
}

private class Watcher implements TextWatcher{
    private XEditText edit;

    public Watcher(XEditText xEditText) {
        this.edit = xEditText;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    @Override
    public void afterTextChanged(Editable s) {
        if(!edit.xTextChanged){
            edit.setXTextChanged(true);
            return;
        }
        XDatePickerView dafarvisTarigi = (XDatePickerView) edit.getRootView().findViewById(dafarvisTarigiId);
        XDatePickerView gacemisTarigi = (XDatePickerView) edit.getRootView().findViewById(gacemisTarigiId);
        String gacTar = gacemisTarigi.getXValue();
        if(gacTar.equals(""))
            return;
        StringTokenizer tk = new StringTokenizer(gacTar, "- ");
        int gacMonth = Integer.parseInt(tk.nextToken());
        int gacDay = Integer.parseInt(tk.nextToken());
        int gacYear = Integer.parseInt(tk.nextToken());
        if(s.toString().equals("")){
            dafarvisTarigi.setXTextChanged(false);
            dafarvisTarigi.setXValue(getResources().getString(R.string.x_dat_view_txt));
        } else {
            int months = Integer.parseInt(String.valueOf(s.toString()));
            int addYear = (months + gacMonth) / 12;
            int addMonth = months - addYear * 12;
            dafarvisTarigi.setXTextChanged(false);
            dafarvisTarigi.setXValue(new StringBuilder().append(gacMonth + addMonth)
                    .append("-").append(gacDay).append("-").append(gacYear + addYear).append(" ").toString());
        }
    }
}

}

x_edittext_view.xml 布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
    android:id="@+id/label"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_weight="@dimen/textLabel_weight" />

<EditText
    android:id="@+id/input"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="@dimen/inputView_weight" />

</LinearLayout>

主要布局

<LinearLayout
        android:id="@+id/linear"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ge.altasoft.custom_views.XEditText
            android:id="@+id/first_name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:inputType="phone"
            custom:textLabel="სახელი"
            custom:viewParameter="opaaa"/>
</LinearLayout>

我认为,该问题出现在TextView课程的CustomView中。我将TextView文本作为自定义XEditText传递给Attribute,然后在创建XEditText期间设置它。但我不确定这是不是问题。

编辑1: 关于我的主要活动:我正在使用ViewPager,这是我使用此布局的片段:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.io.Serializable;
import java.util.ArrayList;
import ge.altasoft.Item.DetailsItemI;
import ge.altasoft.controllers.ViewFillerController;

public class OrdinaryFragment extends Fragment implements Serializable{
    private static final String LAYOUT_ID = "LayoutId";
    private int layoutId;

    public static final String ARG_SECTION_NUMBER = "section_number";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    this.setRetainInstance(true);
    layoutId = getArguments().getInt(LAYOUT_ID);

    View rootView = inflater.inflate(layoutId, container, false);

    ArrayList<DetailsItemI> list = (ArrayList<DetailsItemI>)getArguments().getSerializable("ViewData");
    ViewFillerController viewFiller = new ViewFillerController();
    viewFiller.fillTheView(rootView, list);

    return rootView;
}

}

感谢Advnace。

1 个答案:

答案 0 :(得分:0)

我找到了问题的Solution

问题出在Bad Cast,正如Error告诉我的那样。

正如我所说,我有很多Custom Views,所有这些都由2个组成部分组成:TextView和一些Input Type View。所有TextViews和所有Input Type Views都有相同的Id - s,尽管它是类型。

例如,如果我有2个Custom ViewsEditText TypeSpinner Type,那么在方向更改时,android会尝试cast editText SavedStateSpinner SavedState,应用程序崩溃了。

所以我刚刚改变了Id - s,一切顺利。

感谢大家,感谢您的帮助。