2015-04-07 78 views
1

我正在尝试创建一个待办事项列表,就像“google keep”android应用程序一样。 基本上,我需要一个带有2个列表的滚动布局:其中一个选中的项目,以及一个未选中的项目。 未经检查的列表应该有一个选项,以拖动&删除项目以改变它们的位置。 我唯一的问题是,我无法在recyclerview中使用width = wrap_content,并且我发现在我尝试拖放&时发现应用程序崩溃。Recycler view wrap_content with drag and drop

因为我使用拖动&下降this library.

我的布局:

<ScrollView 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 

android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fillViewport="true" 
tools:context="views.fragments.ItemsFragment"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 

     <AutoCompleteTextView 
      android:id="@+id/fragment_items_atv_name" 
      android:layout_width="0dp" 
      android:layout_weight="1" 
      android:layout_height="wrap_content" /> 

     <Button 
      android:id="@+id/fragment_items_btn_add" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:padding="8dp" 
      android:text="@string/add" /> 

    </LinearLayout> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical"> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/fragment_items_lv_unchecked_list" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/fragment_items_lv_checked_list" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

     <TextView 
      android:id="@+id/fragment_items_tv_empty" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center" 
      android:text="Empty list" 
      android:visibility="gone" /> 

    </LinearLayout> 
</LinearLayout> 
</ScrollView> 

我用

public class MyLinearLayoutManager extends LinearLayoutManager { 

public MyLinearLayoutManager(Context context) { 
    super(context, VERTICAL, false); 
} 

private int[] mMeasuredDimension = new int[2]; 

@Override 
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, 
         int widthSpec, int heightSpec) { 
    final int widthMode = View.MeasureSpec.getMode(widthSpec); 
    final int heightMode = View.MeasureSpec.getMode(heightSpec); 
    final int widthSize = View.MeasureSpec.getSize(widthSpec); 
    final int heightSize = View.MeasureSpec.getSize(heightSpec); 
    int width = 0; 
    int height = 0; 
    for (int i = 0; i < getItemCount(); i++) { 
     measureScrapChild(recycler, i, 
       View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), 
       View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), 
       mMeasuredDimension); 

     if (getOrientation() == HORIZONTAL) { 
      width = width + mMeasuredDimension[0]; 
      if (i == 0) { 
       height = mMeasuredDimension[1]; 
      } 
     } else { 
      height = height + mMeasuredDimension[1]; 
      if (i == 0) { 
       width = mMeasuredDimension[0]; 
      } 
     } 
    } 
    switch (widthMode) { 
     case View.MeasureSpec.EXACTLY: 
      width = widthSize; 
     case View.MeasureSpec.AT_MOST: 
     case View.MeasureSpec.UNSPECIFIED: 
    } 

    switch (heightMode) { 
     case View.MeasureSpec.EXACTLY: 
      height = heightSize; 
     case View.MeasureSpec.AT_MOST: 
     case View.MeasureSpec.UNSPECIFIED: 
    } 

    setMeasuredDimension(width, height); 
} 

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, 
           int heightSpec, int[] measuredDimension) { 
    View view = recycler.getViewForPosition(position); 
    if (view != null) { 
     RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); 
     int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, 
       getPaddingLeft() + getPaddingRight(), p.width); 
     int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, 
       getPaddingTop() + getPaddingBottom(), p.height); 
     view.measure(childWidthSpec, childHeightSpec); 
     measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; 
     measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; 
     recycler.recycleView(view); 
    } 
} 
} 

回答

0

您可以使用ItemTouchHelper在supportv7,并实现simplecallback,喜欢的布局管理器此:

 mSimpleCallback = new ItemTouchHelper.SimpleCallback(
      ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT|ItemTouchHelper.UP|ItemTouchHelper.DOWN, 0) { 
     @Override 
     public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
      int fromPosition = viewHolder.getAdapterPosition();//得到拖动ViewHolder的position 
      int toPosition = target.getAdapterPosition();//得到目标ViewHolder的position 
      List<NHUser.DescriptionEntity> datas = mItemAdapter.getData(); 
      if (fromPosition < toPosition) { 
       //分别把中间所有的item的位置重新交换 
       for (int i = fromPosition; i < toPosition; i++) { 
        Collections.swap(datas, i, i + 1); 
       } 
      } else { 
       for (int i = fromPosition; i > toPosition; i--) { 
        Collections.swap(datas, i, i - 1); 
       } 
      } 
      mItemAdapter.notifyItemMoved(fromPosition, toPosition); 
      return true; 
     } 

     @Override 
     public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 

     } 

    };