【问题标题】:change row background of a listview when swipe滑动时更改列表视图的行背景
【发布时间】:2014-05-11 13:52:15
【问题描述】:

我正在使用 47deg 库来实现列表视图的滑动手势:https://github.com/47deg/android-swipelistview

我想在滑动后更改每一行的背景,但我遇到了 2 个问题。

第一个问题是,例如,当我滑动第一行时,它的背景颜色会完全改变,但在我滚动列表后,我看到其他一些行的背景发生了变化。我搜索了很多,发现这个问题与在 listview 中重用视图有关,但我不知道应该如何解决我的问题。

第二个问题是,在我滑动它们之后,只有列表行的前半部分受到影响。实际上,当我滑动后半行时,我会出错并强制关闭。也许这个问题与第一个有关,我不确定。

这是我的适配器类:

public class WordsListAdapter extends BaseAdapter {

private List<WordsItem> data;
private Context context;

public WordsListAdapter(Context context, List<WordsItem> data){
    this.data = data;
    this.context = context;
}

@Override
public int getCount() {
    return data.size();
}

@Override
public WordsItem getItem(int position) {
    return data.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final WordsItem item = getItem(position);
    ViewHolder holder;
    if (convertView == null) {
        LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = li.inflate(R.layout.custom_row, parent, false);
        holder = new ViewHolder();
        holder.itemName = (TextView) convertView.findViewById(R.id.example_itemname);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    ((SwipeListView)parent).recycle(convertView, position);

    holder.itemName.setText(item.getItemName());

    return convertView;
}

private static class ViewHolder{
    public TextView itemName;
}

}

这是包含 swipelistview 的活动:

public class WordsActivity extends Activity {

private WordsListAdapter adapter;
private List<WordsItem> data;
private int i;

private SwipeListView swipeListView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_words);

    data = new ArrayList<WordsItem>();

    adapter = new WordsListAdapter(this, data);

    swipeListView = (SwipeListView) findViewById(R.id.example_swipe_lv_list);

    swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() {
      @Override
      public void onOpened(int position, boolean toRight) {
        swipeListView.closeAnimate(position);
      }

      @Override
      public void onClosed(int position, boolean fromRight) {
      }

      @Override
      public void onListChanged() {
      }

      @Override
      public void onMove(int position, float x) {
      }

      @Override
      public void onStartOpen(int position, int action, boolean right) {
            if (right) {
                swipeListView.getChildAt(position).findViewById(R.id.front).setBackgroundColor(Color.GREEN);
              } else {
                swipeListView.getChildAt(position).findViewById(R.id.front).setBackgroundColor(Color.RED);
              }
          }
      }

      @Override
      public void onStartClose(int position, boolean right) {
          Log.d("swipe", String.format("onStartClose %d", position));
      }

      @Override
      public void onClickFrontView(int position) {
          Log.d("swipe", String.format("onClickFrontView %d", position));
          Toast.makeText(WordsActivity.this, "Clicked",Toast.LENGTH_SHORT).show();

      }

      @Override
      public void onClickBackView(int position) {
          Log.d("swipe", String.format("onClickBackView %d", position));

          swipeListView.closeAnimate(position);//when you touch back view it will close
      }

      @Override
      public void onDismiss(int[] reverseSortedPositions) {

      }

  });

    swipeListView.setAdapter(adapter);

    reload();

    i = 0;

    for(String word : itemData){
        data.add(new WordsItem("item " + i));
        i++;
    }

    adapter.notifyDataSetChanged();

}

private void reload(){
    swipeListView.setSwipeMode(SwipeListView.SWIPE_MODE_BOTH); // there are five swiping modes
    swipeListView.setSwipeActionLeft(SwipeListView.SWIPE_ACTION_REVEAL); //there are four swipe actions 
    swipeListView.setSwipeActionRight(SwipeListView.SWIPE_ACTION_REVEAL);
    swipeListView.setOffsetLeft(convertDpToPixel(300f)); // left side offset
    swipeListView.setOffsetRight(convertDpToPixel(300f)); // right side offset
    swipeListView.setAnimationTime(100); // Animation time
    swipeListView.setSwipeOpenOnLongPress(true);
}

public int convertDpToPixel(float dp) {
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return (int) px;
}

}

【问题讨论】:

  • 在您的适配器类中,您已经膨胀了 xml 布局“custom_row”。在 xml 中,您必须为滑动列表视图的两侧定义布局。例如:背面和正面布局。您可以更改它们的背景颜色..

标签: android listview swipe


【解决方案1】:

您可以做的是在您的activity 中创建一个callback 并在您的适配器中实现该interface,这样您就可以通过您的callback 发送位置来知道哪个positions onStartOpen()onOpen() 然后,一旦您的适配器识别这些位置,getView() 也会识别这些位置,您就可以只为这些位置放置更改背景的逻辑。

PS - 每当您因为回收而尝试修改 listview's 单个视图时,您将永远无法获得您想要的结果,因此将所有与视图相关的任务委派给您的 listview's adapter 很重要

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多