自定义视图中的微调器初始化

时间:2014-11-19 11:36:40

标签: android spinner android-custom-view

我尝试制作自定义视图,但我对旋转器有问题。 当我启动应用程序时,一切正常。读取首选项并且微调器setSelection方法工作得很好(显示图片没问题)。 当我更改微调器值时,也没有问题:保存首选项,当我启动应用程序时,将显示新选项。

旋转设备时出现问题,我的所有微调器值都重置为最后一个微调器值(我的代码中为vv2)。我真的不明白......

before rotating device

after rotating device

这是我的代码:

widget_value_view.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
    <Spinner
        android:id="@+id/my_spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@android:color/transparent" />

    <TextView
        android:id="@+id/my_value_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_centerVertical="true"
        android:background="@android:color/transparent" />
</merge>

ValueView.java类:

package com.example.spinnertest;
import java.util.Arrays;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

public class ValueView extends LinearLayout {

    protected TextView mValueTv = null;
    protected Spinner mSpinner = null;
    protected List<String> mChoiceList;

    private MySpinnerAdapter mSpinnerAdapter;

    public ValueView(Context context) {
        super(context);
    }

    public ValueView(Context context, AttributeSet attributes){
        super(context,attributes);

        TypedArray a = context.getTheme().obtainStyledAttributes(attributes,R.styleable.ValueView,0, 0);
        try {
            String valueList = a.getString(R.styleable.ValueView_valueList);
            mChoiceList = Arrays.asList(valueList.split("\\|"));
        } finally {
            a.recycle();
        }

        setOrientation(LinearLayout.HORIZONTAL);
        setGravity(Gravity.CENTER_VERTICAL);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.widget_value_view, this, true);

        mSpinner = (Spinner) getChildAt(0);
        mValueTv = (TextView) getChildAt(1);

        mSpinnerAdapter = new MySpinnerAdapter(context, mChoiceList);
        mSpinner.setAdapter(mSpinnerAdapter);
    }

    /**
     * Change textview value
     */
    public void setValue(double value,String format){
        mValueTv.setText("todo");
        invalidate();
        requestLayout();
    }

    /**
     * Set the current item of the spinner
     * @param position of the item
     */
    public void setSelection(int position, boolean animate) {
        // mSpinnerAdapter.notifyDataSetChanged();
        mSpinner.setSelection(position,animate);
        // invalidate();
        // requestLayout();
    }

    public int getSelectedItemPosition() {
        return mSpinner.getSelectedItemPosition();
    }

}

在这个类中,我使用一个带有2个布局和一个类的适配器: MySpinnerAdapter.java

package com.example.spinnertest;

import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MySpinnerAdapter extends BaseAdapter {

    public static final String ITEM_ALTITUDE = "altitude";
    public static final String ITEM_SPEED = "speed";
    public static final String ITEM_DISTANCE = "distance";
    private static final String LOG_TAG = "SPINNER_TEST";

    private Context mContext;
    private List<String> mChoiceList;

    public MySpinnerAdapter(Context context, List<String> values) {
        this.mContext = context;
        this.mChoiceList = values;
    }

    @Override
    public int getCount() {
        return mChoiceList.size();
    }

    @Override
    public Object getItem(int position) {
        return mChoiceList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layout.inflate(R.layout.item_spinner_value, null);
        }
        ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_value_iv);
        Log.d(LOG_TAG,"Spinner Adapter position = " + String.valueOf(position));
        imView.setImageResource(getSpinnerItemImage(position));
        return convertView;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layout.inflate(R.layout.item_spinner_list, null);
        }
        ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_list_iv);
        TextView textView = (TextView) convertView.findViewById(R.id.item_spinner_list_tv);
        textView.setText(mChoiceList.get(position));
        imView.setImageResource(getSpinnerItemImageSmall(position));
        return convertView;
    }

    private int getSpinnerItemImageSmall(int position) {
        String item = mChoiceList.get(position);
        if (item.equals(ITEM_ALTITUDE)) {
            return R.drawable.altitude_small;
        } else if (item.equals(ITEM_DISTANCE)) {
            return R.drawable.distance_small;
        } else if (item.equals(ITEM_SPEED)) {
            return R.drawable.vitesse_small;
        } else {
            return R.drawable.date_small;
        }
    }

    private int getSpinnerItemImage(int position) {
        String item = mChoiceList.get(position);
        if (item.equals(ITEM_ALTITUDE)) {
            return R.drawable.altitude;
        } else if (item.equals(ITEM_DISTANCE)) {
            return R.drawable.distance;
        } else if (item.equals(ITEM_SPEED)) {
            return R.drawable.vitesse;
        } else {
            return R.drawable.date;
        }
    }
}

和2布局item_spinner_list.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" >

    <ImageView
        android:id="@+id/item_spinner_list_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:padding="5dp"
        android:src="@android:drawable/ic_menu_gallery" />

    <TextView
        android:id="@+id/item_spinner_list_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:padding="5dp"
        android:layout_toRightOf="@+id/item_spinner_list_iv"
        android:text="Durée" />

</RelativeLayout>

和item_spinner_value.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="@android:color/transparent" >

    <ImageView
        android:id="@+id/item_spinner_value_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:padding="5dp"
        android:src="@android:drawable/ic_menu_gallery" />
</RelativeLayout>

最后是我的MainActivity.java

package com.example.spinnertest;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;

public class MainActivity extends Activity {

    private SharedPreferences mPref;
    private ValueView mVv1;
    private ValueView mVv2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        mVv1 = (ValueView)findViewById(R.id.value1);
        mVv2 = (ValueView)findViewById(R.id.value2);

        mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
        mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
    }

    @Override
    public void onPause() {
        SharedPreferences.Editor editor = mPref.edit();
        editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
        editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
        editor.commit();
        super.onPause();
    }
}

和布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.example.spinnertest"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.spinnertest.ValueView
        android:id="@+id/value1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_margin="10dp"
        android:background="@android:color/transparent"
        custom:valueList="speed|altitude|distance" />

    <com.example.spinnertest.ValueView
        android:id="@+id/value2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/value1"
        android:layout_margin="10dp"
        custom:valueList="speed|altitude|distance" />

</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

我无法解释为什么你的代码不能正常工作,但我宁愿在本地保存微调器的状态(我的意思是在活动中);它是屏幕旋转的正常Android工作流程。

这样的事情:

String MVV1="1";
String MVV2="2";
@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    mVv1 = (ValueView)findViewById(R.id.value1);
    mVv2 = (ValueView)findViewById(R.id.value2);

if (savedInstanceState != null) {
    mVv1.setSelection(savedInstanceState.getInt(MVV1),false);
    mVv2.setSelection(savedInstanceState.getInt(MVV2),false);
}
else{
    mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
    mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
    }
}

@Override
public void onPause() {
    SharedPreferences.Editor editor = mPref.edit();
    editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
    editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
    editor.commit();
    super.onPause();
}

@Override
protected void onSaveInstanceState (Bundle outState) {
     super.onSaveInstanceState(outState);
outState.putInt(MVV1, mVv1.getSelectedItemPosition());
outState.putInt(MVV2, mVv2.getSelectedItemPosition());
}

我的语法可能并不完美,因为我在SO编辑器中编写了它,但希望你明白这一点:一旦Activity暂停,状态就写在Preferences中,但是如果活动旋转(你的方法应该可以工作,但也许是否有一个缓存来访问首选项或某些东西...)然后,它将使用特定的包:它是在屏幕旋转时填充的,并在重新创建屏幕时使用。

测试并说明它是否正常工作;)