Android ListView Recycler волнуется, или мне не удается? - PullRequest
0 голосов
/ 02 февраля 2012

Я создал собственный просмотр списка, который заполняется с помощью файла row.xml.Каждая строка содержит два TextViews и ImageView.Я заполняю TextView из файла JSON (но это работает нормально, поэтому я думаю, что вы можете смело игнорировать это), и я заполняю ImageView на основе SharedPreferences ... в этом и заключается проблема.

В основномЛогика такова: кто-то нажимает на строку в просмотре списка, если соответствующее действие завершено успешно, я информирую SharedPreferences, а затем, как только пользователь возвращается в список, переключатель / регистр читает файл SharedPreferences и обновляет ImageView в этом конкретномстрока, чтобы отобразить зеленый значок.Если пользователь не выполняет действие, в представлении ImageView в этой строке отображается красный значок.Рядом с первым незавершенным действием в списке отображается синий значок.

Я делаю это с помощью команды switch / case для SharedPreferences в цикле формирования представления.

Итак ...Моя проблема: я открываю список, все отлично работает.В списке отображается один синий значок, как и ожидалось.Когда я прокручиваю вниз, я вижу еще один синий значок внизу ... которого там быть не должно.ОК, ты думаешь "ты, черт возьми, поменял кодирование".Однако - когда я прокручиваю обратно список вверх, я вижу, что синий значок теперь «перепрыгнул» с ожидаемого элемента списка на следующий.Я снова прокручиваю вниз и вижу, что синий значок умножился - теперь их два в двух разных строках, которых раньше не было.Итак, я выполнил задание.Зеленый значок появляется там, где и должен.Я прокручиваю вверх и вниз несколько раз, и вдруг рядом с разными строками списка появляются 3-4 зеленых значка.

Я могу только догадываться, что переработчик в шоке.Я прав?Что я могу сделать, чтобы это исправить?Я пытался быть хитрым - я использовал setVisibility-GONE для строк, которые там, где просмотр изображения не нужен ... хотя после некоторой прокрутки, вот и все - это раздражает зеленоватым светом, освещающим строку, в которой он не может быть.

public class MainList extends ListActivity {
static SharedPreferences statusSettings;
String jsonString;
static JSONObject json;
static JSONArray arrayTest;
static int bob = 3;


@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);

    try {
        JSONObject e = arrayTest.getJSONObject(position);
        Intent intent = new Intent();
        intent.putExtra("clientName", e.getString("proj_name"));
        intent.putExtra("clientAddress", e.getString("c_address"));
        intent.putExtra("clientComments", e.getString("comments"));
        intent.putExtra("clientOrder", e.getString("order"));
        intent.setClass(MainList.this, ClientDetails.class);
        MainList.this.startActivity(intent);


    } catch (JSONException e) {
        // TODO Auto-generated catch block
        Log.e("JSON", "Problem creating object from array!");
        e.printStackTrace();
    }
}

private static class EfficientAdapter extends BaseAdapter {
    private LayoutInflater mInflater;


    public EfficientAdapter(Context context) {
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = LayoutInflater.from(context);

    }

    public int getCount() {
        return arrayTest.length();

    }

    public Object getItem(int position) {
        return position;
    }

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

    public View getView(int position, View convertView, ViewGroup parent) {
        // A ViewHolder keeps references to children views to avoid unneccessary calls
        // to findViewById() on each row.
        ViewHolder holder;

        // When convertView is not null, we can reuse it directly, there is no need
        // to reinflate it. We only inflate a new View when the convertView supplied
        // by ListView is null.
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.mainlist, null);

            // Creates a ViewHolder and store references to the two children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.icon = (ImageView) convertView.findViewById(R.id.ivMainIcon);
            holder.textName = (TextView) convertView.findViewById(R.id.tvMainName);
            holder.textAddress = (TextView) convertView.findViewById(R.id.tvMainAddress);


            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

        // Bind the data efficiently with the holder.

        JSONObject e;
        try {
            e = arrayTest.getJSONObject(position);
            holder.textName.setText(e.getString("proj_name"));
            holder.textAddress.setText(e.getString("c_address"));   

            switch (statusSettings.getInt(e.getString("order"), 0)){
                case 1:
                    holder.icon.setVisibility(View.INVISIBLE);
                    break;
                case 2:
                    if(bob == 3){
                        holder.icon.setImageResource(R.drawable.next_delivery);
                        bob = 5;
                    }
                    break;
                case 3:
                    holder.icon.setImageResource(R.drawable.delivered_icon);
                    break;
                case 4:
                    holder.icon.setImageResource(R.drawable.undelivered_icon);
                    break;
            }


        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            Log.e("JSON", "Couldn't put one of JSON arrays into object");
            e1.printStackTrace();
        }

        return convertView;
    }

    static class ViewHolder {
        ImageView icon;
        TextView textName;
        TextView textAddress;

    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    jsonString = getIntent().getExtras().getString("jsonString");
    try {
        json = new JSONObject(jsonString);
        arrayTest = json.getJSONArray("client_list");
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        Log.e("JSON", "Couldn't create the JSON Array");
        e.printStackTrace();
    }
    setListAdapter(new EfficientAdapter(this));

}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    bob = 3;        
    statusSettings = getSharedPreferences("status", 0);

    setListAdapter(new EfficientAdapter(this));
}


}

Любая помощь будет принята с благодарностью.

/ edit: если вам это нужно - вот файл row.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/LinearLayout02"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" >

    <TextView
        android:id="@+id/tvMainName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:text="Large Text"
        android:textColor="#FFFFFF"
        android:textSize="25dp" />

    <ImageView
        android:id="@+id/ivMainIcon"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_gravity="bottom"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:layout_weight="0"
        android:scaleType="fitXY" />
</LinearLayout>

<TextView
    android:id="@+id/tvMainAddress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingBottom="5dp"
    android:text="TextView"
    android:textSize="15dp" />

</LinearLayout>

Обновленный переключатель/ Дело (любезно предоставлено Бригамом) ... все еще использующее половинное решение с переменной bob.По крайней мере, теперь все работает как надо!:

switch (statusSettings.getInt(e.getString("order"), 0)){
                case 1:
                    holder.icon.setVisibility(View.INVISIBLE);
                    break;
                case 2:
                    if(bob.toString().equalsIgnoreCase("do it") || bob.toString().equalsIgnoreCase(e.getString("proj_name"))){

                        holder.icon.setVisibility(View.VISIBLE);
                        holder.icon.setImageResource(R.drawable.next_delivery);
                        bob = e.getString("proj_name");
                    }else{
                        holder.icon.setVisibility(View.INVISIBLE);
                    }
                    break;
                case 3:
                    holder.icon.setVisibility(View.VISIBLE);
                    holder.icon.setImageResource(R.drawable.delivered_icon);
                    break;
                case 4:
                    holder.icon.setVisibility(View.VISIBLE);
                    holder.icon.setImageResource(R.drawable.undelivered_icon);
                    break;
                default:
                    holder.icon.setVisibility(View.INVISIBLE);
                    break;
            }

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

В вашем case 2 вы устанавливаете изображение только если bob == 3. Вы должны добавить предложение else и сделать изображение невидимым, когда bob != 3. Вы также должны убедиться, что значок отображается до оператора switch, поскольку в большинстве случаев он должен быть видимым.

Вам также следует рассмотреть возможность добавления регистра по умолчанию к вашему оператору switch.

        holder.icon.setVisibility(View.VISIBLE);
        switch (statusSettings.getInt(e.getString("order"), 0)){
            case 1:
                holder.icon.setVisibility(View.INVISIBLE);
                break;
            case 2:
                if(bob == 3){
                    holder.icon.setImageResource(R.drawable.next_delivery);
                    bob = 5;
                } else {
                    holder.icon.setVisibility(View.INVISIBLE);
                }
                break;
            case 3:
                holder.icon.setImageResource(R.drawable.delivered_icon);
                break;
            case 4:
                holder.icon.setImageResource(R.drawable.undelivered_icon);
                break;
            default:
                holder.icon.setVisibility(View.INVISIBLE);
                break;
        }
0 голосов
/ 15 июня 2012

Другой вариант - отключить утилизацию.Возможно, вы не захотите этого делать, но все, что вам нужно сделать, это удалить convertView == null, и это еще оператор.Это предотвратит повторное использование артефактов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...