【问题标题】:ArrayAdapter strange behaviour with id when items's height exceed Listview height当项目的高度超过 Listview 高度时,带有 id 的 ArrayAdapter 奇怪行为
【发布时间】:2015-08-13 09:02:00
【问题描述】:

我在使用 ArrayAdapter 时遇到了一个奇怪的行为。

当listview item 的数量超过listView 的高度时(比如在item 8 之后),下一个item 得到id 0 而不是id 9。

在我看来,此类问题已通过 convertView here 进行了解释,但我以相同的方式使用它(我认为)。

以下代码是我的 ArrayAdapter。

 public class StepsAdapter extends ArrayAdapter<String> {


    Context context;
    List<String> steps;

    public StepsAdapter(Context context, int resourceId, List<String> steps) {
        super(context, resourceId, steps);
        this.context = context;
    }

    private class ViewHolder {
        EditText stepValue;
        ImageView removeStep;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        final String step = getItem(position);

        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.row_step, null);
            holder = new ViewHolder();
            holder.stepValue = (EditText) convertView.findViewById(R.id.stepEdit);
            holder.removeStep = (ImageView) convertView.findViewById(R.id.removeStep);
            holder.stepValue.setText(step);

            holder.removeStep.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context,"* Remove id step " + position, Toast.LENGTH_LONG).show();
                    steps.remove(position);
                    notifyDataSetChanged();
                }
            });

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        return convertView;
    }
 }

然后是我的主要活动,我获取现有数据并将其放入我的 listView、添加按钮和保存按钮。

        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.add_game);

            mContext = getApplicationContext();

            steps = new ArrayList<String>();
            stepsAdapter = new StepsAdapter(mContext,R.layout.row_step,steps);

            Gson gson = new GsonBuilder().create();
            game = gson.fromJson(gameJson, Games.class);

            /*
             * Settings values
             */

            gameNameValue.setText(game.getName());
            gameBackgroundPreview.setBackgroundColor(game.getColor());
            colorSelected = game.getColor();

            for(int i = 0; i < game.getSteps().size() ; i++){
                //steps.add(game.getSteps().get(i).toString());
                //notifyDataSetChanged();
                stepsAdapter.add(game.getSteps().get(i).toString());
            }

            final ListView listSteps = (ListView) findViewById(R.id.listViewSteps);

            listSteps.setAdapter(stepsAdapter);
            gameNameValue.setText(gameName);


            addSteps.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    stepsId = steps.size();
                    Toast.makeText(getApplicationContext(), "addSteps : " + stepsId, Toast.LENGTH_LONG).show();
                    stepsAdapter.insert("newstep", stepsId);
                }
            });

            buttonSaveGame.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String valueEditGameName = gameNameValue.getText().toString();
                    int valueColorBackaground = colorSelected;
                    String picture = "testPic";

                    for(int i=0; i < listSteps.getChildCount(); i++) {
                        LinearLayout rowLayout = (LinearLayout) listSteps.getChildAt(i);
                        //Log.e(TAG, ">> :) layout  >>" + listSteps.getChildAt(i).getClass().getName());
                        EditText editRow = (EditText) rowLayout.getChildAt(0);
                        stepsValues.add(editRow.getText().toString());
                        //Log.e(TAG, ">> :) inside layout >>" + editRow.getText().toString());
                    }

                    if(valueEditGameName.trim().length() > 0 && picture.trim().length() >0 ){

                        Games game = new Games(valueEditGameName,valueColorBackaground,picture,stepsValues);
                        String goToSave = game.createJson();
                        Log.e(TAG, ">>Saved>>" + goToSave);
                        final CkdFile file = new CkdFile();
                        String saved  = file.writeToSDFile(game.getName(), goToSave);

                        Toast.makeText(mContext, saved, Toast.LENGTH_LONG).show();
                        Intent backToMain = new Intent(mContext,MainActivity.class);
                        startActivity(backToMain);

                    } else {
                        Toast.makeText(mContext, "Fill all texts", Toast.LENGTH_LONG).show();
                    }

                }
            });
         }

我尝试以两种不同的方式添加项目:

  • 通过:列表步骤添加项目
  • 通过 StepsAdapter stepsAdapter 添加项目

两者都给了我相同的行为。

如果有人有线索帮助理解我在实现 ListView/ArrayAdapter 时做错了什么。

提前致谢!

编辑 1: 在每次推送一些日志之后,它理解了奇怪的行为: 我的适配器只有 6 个插槽(限制来自布局中 listview 的大小),当我的 arraylist 有超过 6 个项目时,getView 仅选择 0 到 5 之间的项目。

我现在正在寻找一种方法来获取 ArrayList 中的位置,而不是 arrayadapter 中的位置。

【问题讨论】:

  • 您是否在您的适配器中实现getItemIDgetItemgetCount 方法?
  • 这个方法我没有实现,我只是做了。不过好像都一样。

标签: android android-listview android-arrayadapter


【解决方案1】:

我最近遇到了同样的问题。将以下覆盖添加到适配器:

@Override
public int getViewTypeCount() {
    return getCount();
}

@Override
public int getItemViewType(int position) {
    return position;
}

【讨论】:

  • 发生在 convertview 中,它将第一行循环到 n+1 行,以上两个函数通过将每个位置定义为 convertview 来解决它
  • 好像是一样的,我会添加一些日志并查看我的列表和适配器的状态。
【解决方案2】:

我发现了一个简单的 xml “技巧”来避免这种行为:我为 listView 设置了更大的高度。

<ListView
    android:layout_width="match_parent"
    android:layout_height="1000dp"
    android:layout_gravity="center_horizontal"
    android:id="@+id/listViewSteps"
    android:layout_margin="10dp">
</ListView>

这不是真正的解决,而是接受它......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-19
    • 2020-09-16
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 2023-03-22
    相关资源
    最近更新 更多