当项目的高度超过Listview高度时,ArrayAdapter带有id的奇怪行为

时间:2015-05-30 14:43:02

标签: android android-listview android-arrayadapter

我使用ArrayAdapter面对一种奇怪的行为。

当listview项的数量超过listView的高度时(比如第8项之后),下一项获取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个插槽(限制来自布局中列表视图的大小),当我的arraylist有超过6个项目时,getView只选择0到5之间的项目。

我现在正在搜索获取ArrayList中位置的方法,而不是arrayadapter中的位置。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我找到了一个简单的xml“技巧”来避免这种行为:我将biger高度设置为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>

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