rView不支持UnsupportedOperationExce

rView不支持UnsupportedOperationExce

从纵向更改为横向时,我想保存实例。但是,当我尝试对我的字母按钮的背景进行restoreInstance并启用时,它会告诉我该错误。
当我注释掉那些代码时,程序运行良好。

这是字母课

public class Letter extends BaseAdapter {

    private String[] letters;
    private LayoutInflater letterInf;

    public Letter(Context c){
        letters = new String[26];
        for(int a = 0; a < letters.length; a++){
            letters[a] = ""+(char)(a+'A');
        }
        letterInf = LayoutInflater.from(c);
    }

    @Override
    public int getCount() {
        return letters.length;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Button btnLetter;
        if(convertView == null){
            btnLetter = (Button) letterInf.inflate(R.layout.letter, null, false);
        }else{
            btnLetter = (Button) convertView;
        }
        btnLetter.setText(letters[position]);
        return btnLetter;
    }
}


这就是我尝试还原onRestoreInstance(整个版本)的方法

 @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    currPart = savedInstanceState.getInt("currPart");
    numChars = savedInstanceState.getInt("numChars");
    numCorr = savedInstanceState.getInt("numCorr");
    int[] savedBodyPartVisibility = savedInstanceState.getIntArray("bodyPartVisibility");
    for(int i = 0; i<savedBodyPartVisibility.length; i++){
        bodyParts[i].setVisibility(savedBodyPartVisibility[i]);
    }
    //saved word
    currWord = savedInstanceState.getString("currWord");
    hint = savedInstanceState.getString("hint");
    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){//get orientation
        tvHint.setText("Hint:"+hint);// if landscape, show hint
        //Toast.makeText(getBaseContext(), "This is landscape!", Toast.LENGTH_SHORT).show();
    }
    charViews = new TextView[currWord.length()];

    wordLayout.removeAllViews();

    for(int c = 0; c<currWord.length(); c++){
        charViews[c] = new TextView(this);
        charViews[c].setText(""+currWord.charAt(c));

        charViews[c].setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        charViews[c].setGravity(Gravity.CENTER);
        charViews[c].setTextColor(Color.WHITE);
        charViews[c].setBackgroundResource(R.drawable.letter_bg);
        wordLayout.addView(charViews[c]);

    }
    //saved charView
    int[] savedCharViewColor = savedInstanceState.getIntArray("charViewColor");
    for(int i = 0; i< savedCharViewColor.length; i++){
        charViews[i].setTextColor(savedCharViewColor[i]);
    }
    //int numLetters = savedInstanceState.getInt("numLetters");
    //letter enable//letter button background color
    boolean[] savedLetterEnable = savedInstanceState.getBooleanArray("letterEnable");
    int[] savedLettersColor = savedInstanceState.getIntArray("lettersColor");
    for(int i = 0; i<savedLetterEnable.length; i++){
        letters.getChildAt(i).setEnabled(savedLetterEnable[i]);
        //letters.getChildAt(i).setBackgroundColor(savedLettersColor[i]);
    }


}

最佳答案

您无法以这种方式还原它,因为视图是在RecyclerView / ListView中回收的。这意味着仅渲染其中一些视图,并且在滚动时会重用已经渲染的视图。

因此,在大多数情况下,数据源中不会有太多子视图作为项目。

正确的方法是将有关项目状态的信息存储在适配器中。

我创建了一个简单的示例,以使您了解它的外观。请注意,setOnSelectedListener(new OnSelectedListener(){...}是伪造的代码,您应该编写适当的侦听器(onClick,或者如果您要使用复选框,然后使用onCheckedCHange或其他根据您的需要的其他东西)。

 public class Letter extends BaseAdapter {

    private String[] letters;
    private LayoutInflater letterInf;
    private Set<String> selectedLetters = new ArraySet();

    public Letter(Context c){
        letters = new String[26];
        for(int a = 0; a < letters.length; a++){
            letters[a] = ""+(char)(a+'A');
        }
        letterInf = LayoutInflater.from(c);
    }

    Set<String> getState() {
        return selectedLetters;
    }

    void restoreState(Set<String> selectedLetters) {
        this.selectedLetters = selectedLetters;
        notifyDataSetInvalidated();
    }

    @Override
    public int getCount() {
        return letters.length;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Button btnLetter;
        if(convertView == null){
            btnLetter = (Button) letterInf.inflate(R.layout.letter, null, false);
        }else{
            btnLetter = (Button) convertView;
        }
        if(selectedLetters.contains(letters[position])) {
            btnLetter.setSelected(true);
        } else {
            btnLetter.setSelected(false);
        }
        btnLetter.setOnSelectedListener(new OnSelectedListener() {
           void onSelected(..., boolean isSelected) {
               if(isSelected) {
                   selectedLetters.add(letters[position]);
               } else {
                   selectedLetters.remove(letters[position]);
               }
           }
        });
        btnLetter.setText(letters[position]);
        return btnLetter;
    }
}


然后,每当您保存状态时,都可以从适配器getState中获取它,并将其放入savedInstanceState中。

无论何时恢复状态,都可以从saveState获取状态并将其放入适配器restoreState

关于android - 如何解决“AdapterView不支持UnsupportedOperationException:addView(View,LayoutParams)”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54740419/

10-12 02:52