Настраиваемый адаптер просмотра списка

Я использовал https://github.com/wdullaer/SwipeActionAdapter чтобы пролистывать каждый элемент в списке.

после того, как я проведу пальцем по одному элементу, текстовое представление увеличится до единицы. Проблема, если я буду прокручивать список, текстовое представление вернется к каждому значению по умолчанию, которое равно 0, и некоторые скрытые элементы также увеличиваются.

Код для события onswipe:

switch (direction) {
   case SwipeDirections.DIRECTION_FAR_LEFT:
        selectedText = (TextView) getViewByPosition(position, getListView()).findViewById(R.id.txtNumber);
        selectedText.setText(String.valueOf(Integer.parseInt(selectedText.getText().toString()) + 1));
        break;

и код адаптера:

JSONArray jsonArray = null;
try {
    jsonArray = new JSONArray(data);

} catch (JSONException e) {
    e.printStackTrace();
}
String[] strArr = new String[jsonArray.length()];
ArrayList<String> arrayList = new ArrayList<String>();

for (int i = 0; i < jsonArray.length(); i++) {
    try {

        strArr[i] = jsonArray.getJSONObject(i).getString("name");
        arrayList.add(jsonArray.getString(i));

        stringAdapter = new ArrayAdapter<String>(
                this,
                R.layout.items,
                R.id.txtName,
                new ArrayList<String>(Arrays.asList(strArr))
        );

        setListAdapter(stringAdapter);
        stringAdapter.notifyDataSetChanged();


    } catch (JSONException e) {
        e.printStackTrace();
    }
}

items.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="100sp"
    android:background="@drawable/listview_style"
    android:padding="8dp"
    android:descendantFocusability="blocksDescendants">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        android:src="@mipmap/ic_launcher"
        android:layout_centerVertical="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/txtName"
        android:textSize="20sp"
        android:gravity="center"
        android:ellipsize="none"
        android:singleLine="false"
        android:scrollHorizontally="false"
        android:layout_centerVertical="true"
        android:layout_marginLeft="20sp"
        android:layout_marginRight="20sp"
        android:layout_toRightOf="@+id/imageView"
        android:layout_toLeftOf="@+id/txtNumber"
        android:layout_toStartOf="@+id/txtNumber"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:id="@+id/txtNumber"
        android:textSize="25sp"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginRight="40dp"
        android:layout_marginEnd="40dp"
        />

</RelativeLayout>

Я думаю, что позиция товара недействительна или вид недействителен. Anyidea, как решить это. Спасибо

ОБНОВЛЕНИЕ Инкремент теперь работает правильно, но имя элемента не заполняется. Смотри приложение название элемента не заполнено

1 ответ

Решение

Проблема в том, что списки читов. Это вид переработки, так что в действительности у вас есть те же самые, что и 10 просмотров, которые вы сейчас видите. Когда вы прокручиваете достаточно далеко, чтобы представление исчезло, оно снова появляется как представление, которое только что появилось. Чтобы сделать это, он избавился от старого представления и попросил адаптер превратить это потерянное представление во что-то, что будет похоже на новое представление (что прекрасно для памяти и быстрого создания представления).

Вот почему ваши элементы исчезают, потому что представления перерабатываются списком с помощью адаптера после того, как вы прокрутите страницу. Если вы действительно хотите это увидеть, попробуйте с помощью пальца повернуть видимость вашего вида в НЕВИДИМОЕ, ​​тогда вы увидите, что виды повсюду просто пропали. Потому что они одинаковые.

Короче говоря, проведите пальцем должны изменить данные, используемые для построения представления. Любые изменения в самом представлении будут либо удалены, либо испортят другие представления (такие вещи, как видимость и.transform() не часто сбрасываются адаптерами), которые на самом деле снова являются одним и тем же представлением.

public class SwipeActivity extends AppCompatActivity {

SwipeActionAdapter mAdapter;

private class YourCustomRowEntry {
    String displayString;
    int swipes;

    public YourCustomRowEntry( String displayString, int swipes) {
        this.swipes = swipes;
        this.displayString = displayString;
    }
}

private class Holder {
    public TextView textName, textNumber;
    public ImageView imageView;
    public Holder(TextView textName, TextView textNumber, ImageView imageView) {
        this.textName = textName;
        this.textNumber = textNumber;
        this.imageView = imageView;
    }
}

ArrayList<YourCustomRowEntry> mDataYouEditThatBacksTheAdapter = new ArrayList<>();

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

    for (int i = 1; i <= 200; i++) {
        mDataYouEditThatBacksTheAdapter.add(new YourCustomRowEntry("Row " + i,0));
    }

    BaseAdapter customAdapter = new BaseAdapter() {
        @Override
        public int getCount() {
            return mDataYouEditThatBacksTheAdapter.size();
        }

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View itemView;
            Holder viewHolder;
            if (convertView != null) {
                itemView = convertView; //if you already made this view, and it's being recycled use that.
                viewHolder = (Holder)convertView.getTag(); //And fetch the already findByViews things.
            }
            else {
                //if this is the first time, inflate the view.
                itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
                TextView textName = (TextView)itemView.findViewById(R.id.txtName);
                TextView textNumber = (TextView)itemView.findViewById(R.id.txtNumber);
                ImageView imageView =  (ImageView)itemView.findViewById(R.id.imageView);
                viewHolder = new Holder(textName,textNumber,imageView);
                itemView.setTag(viewHolder); //store the data in the view's tag.
            }
            YourCustomRowEntry ycre = mDataYouEditThatBacksTheAdapter.get(position);
            viewHolder.textName.setText(ycre.displayString);
            viewHolder.textNumber.setText("" + ycre.swipes); // Gotta tell it that this is a string and not a resource.
            //You would also set the imageView from the saved set of data here too.
            return itemView;
        }
    };

    ListView listView = (ListView)findViewById(R.id.myActivitysListView);

    // Wrap your content in a SwipeActionAdapter
    mAdapter = new SwipeActionAdapter(customAdapter);

    // Pass a reference of your ListView to the SwipeActionAdapter
    mAdapter.setListView(listView);

    // Set the SwipeActionAdapter as the Adapter for your ListView
    listView.setAdapter(mAdapter);

    // Listen to swipes
    mAdapter.setSwipeActionListener(new SwipeActionAdapter.SwipeActionListener() {
        @Override
        public boolean hasActions(int position) {
            // All items can be swiped
            return true;
        }

        @Override
        public boolean shouldDismiss(int position, int direction) {
            // Only dismiss an item when swiping normal left
            return false;
            //return direction == SwipeDirections.DIRECTION_NORMAL_LEFT;
        }

        @Override
        public void onSwipe(int[] positionList, int[] directionList) {
            for (int i = 0; i < positionList.length; i++) {
                int direction = directionList[i];
                int position = positionList[i];
                switch (direction) {
                    case SwipeDirections.DIRECTION_FAR_LEFT:
                        mDataYouEditThatBacksTheAdapter.get(position).swipes++; //add 1 to swipes;
                        mAdapter.notifyDataSetChanged();
                        break;
                    case SwipeDirections.DIRECTION_FAR_RIGHT:
                        mDataYouEditThatBacksTheAdapter.get(position).swipes--; //subtract 1 to swipes;
                        mAdapter.notifyDataSetChanged();
                        break;
                }
            }
        }
    });


}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_swipe, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

}

Видео о том, как оно работает: https://youtu.be/6wPF2OOKu2U

Сохраните массив, который вы используете для поддержки вашего списка. Вы должны иметь это, чтобы вы могли изменить его и получить адаптер для создания новых представлений. notifyDataSetChanged(), и он обновляет и перестраивает представления из исходной структуры данных, которую он сохранил. Это означает, что вам нужно изменить эти данные, а не представление. Это правильно пишет класс и использует его для построения представлений.

Другие вопросы по тегам