【问题标题】:Save Instance of Custom view保存自定义视图的实例
【发布时间】:2017-02-21 21:19:37
【问题描述】:

我尝试在 Android Studio 中编写自定义视图。到目前为止,上帝。

一切正常,除了保存视图的实例。

视图包含 4 个元素

  • Linear Layout(包含 2 个TextViews
  • ImageView

在旋转屏幕或按返回并重新打开应用程序后,ImageView 不会保存它的状态/图像。它恢复为默认图像!

我尝试了多种方法,但没有任何效果。

onSaveInstanceState()onRestoreInstanceState(Parcelable) 从未被调用,我不知道为什么 :(

希望你能帮助我。

#edit: 添加问题的 GIF GIF of Problem

到目前为止,这是我的代码:

package de.codersgen.activitycontrol;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by Ben Ny on 21.02.2017.
 */

public class ActivityView extends LinearLayout {

    private Context context;

    private static String STATE_SUPER_CLASS = "ActivitySuperClass";
    private static String STATE_HEADER_TEXT = "HeaderText";
    private static String STATE_INFO_TEXT = "InfoText";
    private static String STATE_STATUS_IMAGE = "StatusImage";

    private LinearLayout mTextContainer;
    private TextView mHeaderText;
    private TextView mInfoText;
    private ImageView mStatusImage;
    private int state = 0;
    private int[] stateImages = {
            R.drawable.infosign_black_24dp,
            R.drawable.check_black_24dp
    };

    public ActivityView(Context context) {
        super(context);
        this.context = context;
        initializeViews(context);
    }

    public ActivityView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initializeViews(context);
    }

    public ActivityView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        initializeViews(context);
    }

    private void initializeViews(Context context) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.container_view, this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mTextContainer = (LinearLayout) this
                .findViewById(R.id.textContainer);
        mHeaderText = (TextView) this
                .findViewById(R.id.headerText);
        mInfoText = (TextView) this
                .findViewById(R.id.infoText);
        mStatusImage = (ImageView) this
                .findViewById(R.id.statusImage);
        mStatusImage
                .setBackgroundResource(android.R.drawable.ic_media_next);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        super.onSaveInstanceState();
        Toast.makeText(context, "SAVE", Toast.LENGTH_SHORT).show();
        Bundle bundle = new Bundle();
        bundle.putParcelable(STATE_SUPER_CLASS,
                            super.onSaveInstanceState());
        bundle.putString(STATE_HEADER_TEXT, mHeaderText.getText().toString());
        bundle.putString(STATE_INFO_TEXT, mInfoText.getText().toString());
        bundle.putInt(STATE_STATUS_IMAGE, state);
        return bundle;
    }


    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            super.onRestoreInstanceState(bundle.getParcelable(STATE_SUPER_CLASS));
            setHeaderText("TEST");
            setInfotext(bundle.getString(STATE_INFO_TEXT));
            if (bundle.getInt(STATE_STATUS_IMAGE) == 1)
                setStatusFinish();
            else
                setStatusUnfinished();
        }
        else {
            super.onRestoreInstanceState(state);
        }
    }

    @Override
    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
        super.dispatchFreezeSelfOnly(container);
    }

    @Override
    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
        super.dispatchThawSelfOnly(container);
    }

    public String getHeaderText() {
        mHeaderText = (TextView) this
                .findViewById(R.id.headerText);
        return mHeaderText.getText().toString();
    }

    public void setHeaderText(String text) {
        mHeaderText = (TextView) this
                .findViewById(R.id.headerText);
        mHeaderText.setText(text);
    }

    public String getInfoText() {
        mInfoText = (TextView) this
                .findViewById(R.id.infoText);
        return mInfoText.getText().toString();
    }

    public void setInfotext(String text) {
        mInfoText = (TextView) this
                .findViewById(R.id.infoText);
        mInfoText.setText(text);
    }

    public void setStatusUnfinished() {
        mStatusImage = (ImageView) this
                .findViewById(R.id.statusImage);
        state = 0;
        mStatusImage.setImageResource(R.drawable.infosign_black_24dp);
    }

    public void setStatusFinish() {
        mStatusImage = (ImageView) this
                .findViewById(R.id.statusImage);
        state = 1;
        mStatusImage.setImageResource(R.drawable.check_black_24dp);
    }

    public void setStatusOnClickListener(OnClickListener listener) {
        mStatusImage = (ImageView) this
                .findViewById(R.id.statusImage);
        mStatusImage.setOnClickListener(listener);
    }
}

edit number2:添加我的 CustomView 的 XML

    <?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:id="@+id/textContainer"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        <TextView
            android:id="@+id/headerText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:textColor="@android:color/black"
            android:text="Example Header"
            android:textSize="19sp">
        </TextView>

        <TextView
            android:id="@+id/infoText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/holo_red_dark"
            android:paddingLeft="10dp"
            android:paddingBottom="3dp"
            android:text="Info Header"
            android:textSize="12sp">
        </TextView>
    </LinearLayout>
    <ImageView
        android:id="@+id/statusImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:padding="5dp"
        android:src="@drawable/add_black_24dp"
        android:layout_weight="0.001">
    </ImageView>
</merge>

【问题讨论】:

  • 我不知道您为什么要创建自定义视图而不是使用 RecyclerView 或 ListView。
  • 检查this
  • 我没有在设计器中添加视图。我在我的应用程序运行时添加它们。所以更容易控制这个原因。 @AtefHares 这对我没有帮助。因为永远不会调用函数。 :(
  • 您必须分配一个 ID 才能工作。 stackoverflow.com/a/28586444/3300893
  • @septemberboy7 无法将 ID 添加到我的 XML 文件中的“合并”元素...在上面编辑我的 XML 文件.. :/

标签: java android android-custom-view savestate


【解决方案1】:

您可以添加一个可以代表您的“计数”的样式属性,然后在布局构造函数中获取样式并增加“计数”

【讨论】:

  • 你有一个例子来说明你的意思吗?不明白你的意思:/
  • 在 attrs.xml 添加:&lt;declare-styleable name="Identifier"&gt; &lt;attr name="counter" format="integer"/&gt; &lt;/declare-styleable&gt; 然后在您的布局 xml 中,添加:xmlns:custom="http://schemas.android.com/apk/res-auto"。如果您希望您的 xml 访问 custom:counter,您会这样做。否则,在扩展布局的 layoutfile.java 中,有 2 个构造函数采用 AttributeSet 参数。 TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.Identifier, 0, 0); Integer counter = a.getInt(R.styleable.Identifier_counter); a.recycle();
猜你喜欢
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 2013-11-29
  • 2013-11-01
  • 1970-01-01
相关资源
最近更新 更多