অ্যান্ড্রয়েড গ্রিডলেআউটম্যানজারের সাথে পুনর্ব্যবহারযোগ্যতে শেষের উপাদানটির নীচে ব্যবধান যোগ করে


85

আমি RecyclerViewসাথে শেষ উপাদান সারি নীচে ব্যবধান যোগ করার চেষ্টা করছি GridLayoutManager। আমি ItemDecorationনীচের প্যাডিং সহ এই উদ্দেশ্যে কাস্টমটি ব্যবহার করেছি যখন এর শেষ উপাদানটি নিম্নরূপ:

public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int space;
private int bottomSpace = 0;

public SpaceItemDecoration(int space, int bottomSpace) {
    this.space = space;
    this.bottomSpace = bottomSpace;
}

public SpaceItemDecoration(int space) {
    this.space = space;
    this.bottomSpace = 0;
}

@Override
public void getItemOffsets(Rect outRect, View view,
                           RecyclerView parent, RecyclerView.State state) {

    int childCount = parent.getChildCount();
    final int itemPosition = parent.getChildAdapterPosition(view);
    final int itemCount = state.getItemCount();

    outRect.left = space;
    outRect.right = space;
    outRect.bottom = space;
    outRect.top = space;

    if (itemCount > 0 && itemPosition == itemCount - 1) {
        outRect.bottom = bottomSpace;
    }
}
}

তবে এই পদ্ধতির সমস্যাটি হ'ল এটি গ্রিডের মৌলিক উচ্চতাগুলিকে শেষ সারিতে বিভ্রান্ত করেছে। আমি অনুমান করছি যে GridLayoutManagerব্যবধান বামের উপর ভিত্তি করে উপাদানগুলির উচ্চতা পরিবর্তন করে। এটি অর্জনের সঠিক উপায় কী?

এটি একটির জন্য সঠিকভাবে কাজ করবে LinearLayoutManager। শুধু GridLayoutManagerএটির সমস্যাযুক্ত ক্ষেত্রে ।

আপনার FABনীচে নীচে রয়েছে এবং উপরের স্ক্রোল করার জন্য শেষ সারিতে থাকা আইটেমগুলির প্রয়োজন হলে এটি খুব কার্যকর FABthey

উত্তর:


11

এই সমস্যার সমাধান গ্রিডলাউটম্যানেজারের স্প্যানসাইজলুকআপকে ওভাররাইন্ড করার মধ্যে রয়েছে।

ক্রিয়াকলাপ বা খণ্ডের গ্রিডলেআউটম্যানেজারে আপনাকে পরিবর্তন করতে হবে যেখানে আপনি রিসেলারভিউটি ফুটিয়ে তুলছেন।

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //your code 
    recyclerView.addItemDecoration(new PhotoGridMarginDecoration(context));

    // SPAN_COUNT is the number of columns in the Grid View
    GridLayoutManager gridLayoutManager = new GridLayoutManager(context, SPAN_COUNT);

    // With the help of this method you can set span for every type of view
    gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if (list.get(position).getType() == TYPE_HEADER) {
                // Will consume the whole width
                return gridLayoutManager.getSpanCount();
            } else if (list.get(position).getType() == TYPE_CONTENT) {
                // will consume only one part of the SPAN_COUNT
                return 1;
            } else if(list.get(position).getType() == TYPE_FOOTER) {
                // Will consume the whole width
                // Will take care of spaces to be left,
                // if the number of views in a row is not equal to 4
                return gridLayoutManager.getSpanCount();
            }
            return gridLayoutManager.getSpanCount();
        }
    });
    recyclerView.setLayoutManager(gridLayoutManager);
}

439

কেবল একটি প্যাডিং যুক্ত করুন এবং সেট করুন android:clipToPadding="false"

<RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="8dp"
    android:clipToPadding="false" />

এই দুর্দান্ত উত্তর ধন্যবাদ !


4
এটা আমার জন্য এটি। যখন আপনার পুনর্ব্যাবহারকারীগুলিতে সমানভাবে স্থান আইটেম প্রয়োজন তখন দ্রুত 'এন সহজ সমাধান। ধন্যবাদ
খালি 2 কে 12

4
আমি যা খুঁজছিলাম ঠিক এটাই ছিল! ধন্যবাদ!
মারিয়ানো জোরিলা

4
দুর্দান্ত এবং সহজ সমাধান। ধন্যবাদ!
মিখাইল

4
এটি দুর্দান্ত, তবে এটি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ঝরে পড়ে;
স্টিফান হেনিংসেন

6
এটি পুনর্ব্যবহারকারী দৃশ্যের স্ক্রোলবারকে খুব নীচে প্রসারিত করে না। সম্পাদনা করুন: এই android:scrollbarStyle="outsideOverlay"
সেবাস্তিয়ান

8

শুধুমাত্র শেষ আইটেমের ক্ষেত্রে নীচের মার্জিনের জন্য রিসাইক্লার ভিউতে সজ্জা ব্যবহার করা উচিত

recyclerView.addItemDecoration(MemberItemDecoration())

public class MemberItemDecoration extends RecyclerView.ItemDecoration {

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        // only for the last one
        if (parent.getChildAdapterPosition(view) == parent.getAdapter().getItemCount() - 1) {
            outRect.bottom = 50/* set your margin here */;
        }
    }
}

6

আমার অনুরূপ সমস্যা ছিল এবং স্ট্যাক ওভারফ্লোতে অন্য থ্রেডে জবাব দেওয়া হয়েছিল। এই পৃষ্ঠায় অবতরণ করা অন্যদের সহায়তার জন্য, আমি এটি এখানে পুনরায় পোস্ট করব।
অন্য সমস্ত জবাবগুলি পড়ার পরে এবং আমি পুনর্ব্যবহারের জন্য লেআউট এক্সএমএল পরিবর্তনগুলি প্রত্যাশার মতো আমার পুনর্ব্যবহারযোগ্য দর্শনের জন্য কাজ করেছি:

        android:paddingBottom="127px"
        android:clipToPadding="false"
        android:scrollbarStyle="outsideOverlay"  

সম্পূর্ণ বিন্যাসটি দেখতে দেখতে:

<android.support.v7.widget.RecyclerView
        android:id="@+id/library_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="160px"
        android:layout_marginEnd="160px"
        tools:listitem="@layout/library_list_item" />  

এর আগে এবং পরে এর লিঙ্কটি androidblog.us এ দেখুন: অ্যান্ড্রয়েডের পুনরায় পর্যালোচনাটির শেষে স্থান যুক্ত করা আপনার
সম্পর্কে কীভাবে কাজ করে তা আমাকে জানান Let

ডেভিড


3

গ্রিড ভিউতে প্রথম এবং শেষ সারিগুলি সনাক্ত করতে আপনি নীচের কোডটি ব্যবহার করতে পারেন এবং উপরের এবং নীচে অফসেটগুলিকে একইভাবে সেট করতে পারেন।

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
    LayoutParams params = (LayoutParams) view.getLayoutParams();
    int pos = params.getViewLayoutPosition();
    int spanCount = mGridLayoutManager.getSpanCount();

    boolean isFirstRow = pos < spanCount;
    boolean isLastRow = state.getItemCount() - 1 - pos < spanCount;

    if (isFirstRow) {
      outRect.top = top offset value here
    }

    if (isLastRow) {
      outRect.bottom = bottom offset value here
    }
}

// you also need to keep reference to GridLayoutManager to know the span count
private final GridLayoutManager mGridLayoutManager;

2

আপনি যা করতে পারেন তা হ'ল আপনার পুনর্ব্যবহারযোগ্য দৃশ্যে একটি খালি ফুটার যুক্ত করা। আপনার প্যাডিং আপনার ফুটারের আকার হবে।

@Override
public Holder onCreateViewHolder( ViewGroup parent, int viewType) {
    if (viewType == FOOTER) {
        return new FooterHolder();
    }
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
    return new Holder(view);
}

@Override
public void onBindViewHolder(final Holder holder, final int position) {
    //if footer
    if (position == items.getSize() - 1) {
    //do nothing
        return;
    }
    //do regular object bindding

}

@Override
public int getItemViewType(int position) {
    return (position == items.getSize() - 1) ? FOOTER : ITEM_VIEW_TYPE_ITEM;
}

@Override
public int getItemCount() {
    //add one for the footer
    return items.size() + 1;
}

এটি একটি ভাল বিকল্প। তবে এর সাথে আমার সমস্যা হ'ল আমি ইতিমধ্যে একটি কাস্টম আইটেমডেকোরেশন ব্যবহার করছি যা পুনর্ব্যবহারের আইটেম পজিশনের উপর ভিত্তি করে কাজ করে এবং কোন স্থান এবং বিভাজক ইত্যাদি স্থাপন করবে তা স্থির করে Now ব্যবধানে বিভাজকও যুক্ত করে। সুতরাং আমি ভাবছিলাম যে সমস্যাটি সমাধান করার জন্য যদি কেউ কাস্টম আইটেমডেকারেশন ব্যবহার করার চেষ্টা করে।
pratsJ

এছাড়াও লাইনারলআউটআউট ম্যানেজারের ক্ষেত্রে বা গ্রিডের নিচের সারিতে পূর্ণতা থাকলে গ্রিডলআউটআউট ম্যানেজারের ক্ষেত্রে আপনার পদ্ধতিটি ভালভাবে কাজ করবে। অন্যথায় স্থানটি খালি উপাদান স্থানে গ্রিডে যাবে এবং পুরো গ্রিডের নীচে নয়।
প্রাক্তন

0

এই জাতীয় জিনিসগুলির সাথে, এটি আইটেমডেকোরেশন ব্যবহার করে সমাধান করার পরামর্শ দেওয়া হচ্ছে কারণ সেগুলি এর জন্য।

public class ListSpacingDecoration extends RecyclerView.ItemDecoration {

  private static final int VERTICAL = OrientationHelper.VERTICAL;

  private int orientation = -1;
  private int spanCount = -1;
  private int spacing;


  public ListSpacingDecoration(Context context, @DimenRes int spacingDimen) {

    spacing = context.getResources().getDimensionPixelSize(spacingDimen);
  }

  public ListSpacingDecoration(int spacingPx) {

    spacing = spacingPx;
  }

  @Override
  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

    super.getItemOffsets(outRect, view, parent, state);

    if (orientation == -1) {
        orientation = getOrientation(parent);
    }

    if (spanCount == -1) {
        spanCount = getTotalSpan(parent);
    }

    int childCount = parent.getLayoutManager().getItemCount();
    int childIndex = parent.getChildAdapterPosition(view);

    int itemSpanSize = getItemSpanSize(parent, childIndex);
    int spanIndex = getItemSpanIndex(parent, childIndex);

    /* INVALID SPAN */
    if (spanCount < 1) return;

    setSpacings(outRect, parent, childCount, childIndex, itemSpanSize, spanIndex);
  }

  protected void setSpacings(Rect outRect, RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {

    if (isBottomEdge(parent, childCount, childIndex, itemSpanSize, spanIndex)) {
        outRect.bottom = spacing;
    }
  }

  @SuppressWarnings("all")
  protected int getTotalSpan(RecyclerView parent) {

    RecyclerView.LayoutManager mgr = parent.getLayoutManager();
    if (mgr instanceof GridLayoutManager) {
        return ((GridLayoutManager) mgr).getSpanCount();
    } else if (mgr instanceof StaggeredGridLayoutManager) {
        return ((StaggeredGridLayoutManager) mgr).getSpanCount();
    } else if (mgr instanceof LinearLayoutManager) {
        return 1;
    }

    return -1;
  }

  @SuppressWarnings("all")
  protected int getItemSpanSize(RecyclerView parent, int childIndex) {

    RecyclerView.LayoutManager mgr = parent.getLayoutManager();
    if (mgr instanceof GridLayoutManager) {
        return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanSize(childIndex);
    } else if (mgr instanceof StaggeredGridLayoutManager) {
        return 1;
    } else if (mgr instanceof LinearLayoutManager) {
        return 1;
    }

    return -1;
  }

  @SuppressWarnings("all")
  protected int getItemSpanIndex(RecyclerView parent, int childIndex) {

    RecyclerView.LayoutManager mgr = parent.getLayoutManager();
    if (mgr instanceof GridLayoutManager) {
        return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanIndex(childIndex, spanCount);
    } else if (mgr instanceof StaggeredGridLayoutManager) {
        return childIndex % spanCount;
    } else if (mgr instanceof LinearLayoutManager) {
        return 0;
    }

    return -1;
  }

  @SuppressWarnings("all")
  protected int getOrientation(RecyclerView parent) {

    RecyclerView.LayoutManager mgr = parent.getLayoutManager();
    if (mgr instanceof LinearLayoutManager) {
        return ((LinearLayoutManager) mgr).getOrientation();
    } else if (mgr instanceof GridLayoutManager) {
        return ((GridLayoutManager) mgr).getOrientation();
    } else if (mgr instanceof StaggeredGridLayoutManager) {
        return ((StaggeredGridLayoutManager) mgr).getOrientation();
    }

    return VERTICAL;
  }

  protected boolean isBottomEdge(RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {

    if (orientation == VERTICAL) {

        return isLastItemEdgeValid((childIndex >= childCount - spanCount), parent, childCount, childIndex, spanIndex);

    } else {

        return (spanIndex + itemSpanSize) == spanCount;
    }
  }

  protected boolean isLastItemEdgeValid(boolean isOneOfLastItems, RecyclerView parent, int childCount, int childIndex, int spanIndex) {

    int totalSpanRemaining = 0;
    if (isOneOfLastItems) {
        for (int i = childIndex; i < childCount; i++) {
            totalSpanRemaining = totalSpanRemaining + getItemSpanSize(parent, i);
        }
    }

    return isOneOfLastItems && (totalSpanRemaining <= spanCount - spanIndex);
  }
}

আমি এখানে আমার মূল উত্তর থেকে সম্পাদিত একটি অনুলিপি করেছি যা আসলে সমান ব্যবধানের জন্য তবে এটি একই ধারণা।


0

আপনি উত্স কোড থেকে উদাহরণস্বরূপ DividerItemDecoration.java নিতে এবং প্রতিস্থাপন করতে পারে

for (int i = 0; i < childCount; i++)

সঙ্গে

for (int i = 0; i < childCount - 1; i++)

অঙ্কনে ভার্টিকাল () এবং অঙ্কন হরিজন্টাল ()

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.