Tôi gặp sự cố với một trong các bộ điều hợp của mình. Tôi có một lựa chọn các hình ảnh mà tôi hiển thị trong một mạng lưới như sau:RecyclerView - các mục bên ngoài màn hình bỏ qua bố trí đầu tiên vượt qua
này hoạt động tốt khi tôi có một giá trị màn hình duy nhất của các mặt hàng và tất cả họ đều hiển thị tốt. Sự cố xuất hiện khi có nhiều mục để cuộn xuống. Ban đầu khi tôi di chuyển xuống thấp hơn nữa các mục xuất hiện trống, GridLayout
container đang có và mã để hiển thị những hình ảnh được chạy, nhưng họ không xuất hiện trên màn hình như ở đây:
Nếu tôi di chuyển trở lên, sau đó di chuyển xuống một lần nữa, những hình ảnh xuất hiện chính xác nơi họ sẽ:
Nó có vẻ như tôi cần phải làm mới bố trí hoặc cho các renderer rằng một cái gì đó đã thay đổi, nhưng không có gì tôi cố gắng dường như để làm bất cứ điều gì. Tôi đã thử gọi requestLayout
và invalidate
nhưng dường như không giải quyết được vấn đề. Tôi cũng đã đăng ký GlobalOnLayoutListener, nhưng điều đó không có giá nào tốt hơn.
Đây là mã có liên quan:
Đây là từ phương pháp onBindViewHolder
tôi
final GridLayout grid = ((KKAlbumViewHolder) holder).mGridLayout;
grid.removeAllViews();
int width = grid.getWidth();
if(width > 0) {
albumHolder.setPreviewImages(posts);
}else {
albumHolder.itemView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
albumHolder.itemView.removeOnLayoutChangeListener(this);
albumHolder.setPreviewImages(posts);
albumHolder.mGridLayout.invalidate();
}
});
}
Đây là phương pháp tôi sử dụng để bố trí các hình ảnh. Về cơ bản nó đưa hình ảnh ra trong một lưới bất thường, vì vậy nếu có một hình ảnh dài hoặc cao, hình ảnh đó sẽ cố gắng chiếm một hàng đầy đủ hoặc một cột đầy đủ tùy thuộc vào không gian là miễn phí. Lý do tôi thiết lập chiều rộng và chiều cao param như vậy picasso không phàn nàn về phương pháp .fit()
:
public void setPreviewImages(ArrayList<KKPost> posts) {
Picasso picasso = Picasso.with(itemView.getContext());
int space = 0;
int tl = 1 << 0;
int tr = 1 << 1;
int bl = 1 << 2;
int br = 1 << 3;
int lCol = tl | bl;
int rCol = tr | br;
int tRow = tl | tr;
int bRow = bl | br;
int full = lCol | rCol;
boolean hasLongImage = false;
for(KKPost post : posts) {
if(space == full){
break;
}
int margin = 2;
ImageView view = new ImageView(itemView.getContext());
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
view.setBackgroundColor(Color.LTGRAY);
if(posts.size() < 4){
param.columnSpec = GridLayout.spec(0, 2);
param.rowSpec = GridLayout.spec(0, 2);
param.width = mGridLayout.getWidth();
param.height = mGridLayout.getHeight();
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
break;
}
if (post.aspectRatio >= 1.2 && !hasLongImage) {
//landscape
if((space & tRow) == 0){
param.rowSpec = GridLayout.spec(0, 1);
param.columnSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth();
param.bottomMargin = margin;
space |= tRow;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
if((space & bRow) == 0){
param.rowSpec = GridLayout.spec(1, 1);
param.columnSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth();
param.topMargin = margin;
space |= bRow;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
} else if (post.aspectRatio <= 0.8 && post.aspectRatio > 0 && !hasLongImage) {
//portrait
if((space & lCol) == 0){
param.columnSpec = GridLayout.spec(0, 1);
param.rowSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight();
param.width = mGridLayout.getWidth()/2;
param.rightMargin = margin;
space |= lCol;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
if((space & rCol) == 0){
param.columnSpec = GridLayout.spec(1, 1);
param.rowSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight();
param.width = mGridLayout.getWidth()/2;
param.leftMargin = margin;
space |= rCol;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
}
//square or no space or unknown
if((space & tl) == 0){
param.columnSpec = GridLayout.spec(0,1);
param.rowSpec = GridLayout.spec(0,1);
space |= tl;
param.bottomMargin = margin;
param.rightMargin = margin;
}else
if((space & tr) == 0) {
param.columnSpec = GridLayout.spec(1,1);
param.rowSpec = GridLayout.spec(0,1);
space |= tr;
param.bottomMargin = margin;
param.leftMargin = margin;
}else
if((space & bl) == 0){
param.columnSpec = GridLayout.spec(0,1);
param.rowSpec = GridLayout.spec(1,1);
space |= bl;
param.rightMargin = margin;
param.topMargin = margin;
}else
if((space & br) == 0){
param.columnSpec = GridLayout.spec(1,1);
param.rowSpec = GridLayout.spec(1,1);
space |= br;
param.leftMargin = margin;
param.topMargin = margin;
}
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth()/2;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
}
}
}
Tại sao dường như này để bỏ ra trên đèo vẽ đầu tiên cho các mục không rõ ràng ban đầu?
EDIT: Tôi đã làm imageviews một chút refactoring vì vậy tôi có thể tái sử dụng thay vì loại bỏ/tạo mới và đã phát hiện ra rằng những quan điểm được bổ sung đối với những mặt hàng không nhận được một cuộc gọi lại onLayoutChange. Tất cả các mục khác nhận được cuộc gọi lại onLayoutChange và như trước đây, các mục không nhận được cuộc gọi ban đầu, nhận được nó sau khi tôi cuộn lên và cuộn xuống một lần nữa. Xem:
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
view.removeOnLayoutChangeListener(this);
picasso.load(post.url).into(view);
}
});
Edit: Tháng Mười Một 15
Đây là xml cho bố trí viewholder
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:id="@+id/album_card_view"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
card_view:cardCornerRadius="@dimen/feed_card_corner_radius"
card_view:cardElevation="@dimen/cardview_default_elevation"
card_view:cardMaxElevation="@dimen/cardview_default_elevation"
card_view:cardUseCompatPadding="true"
xmlns:autofit="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/percent_layout">
<GridLayout
android:background="@color/white"
android:id="@+id/preview_grid_layout"
android:columnCount="2"
android:rowCount="2"
android:alignmentMode="alignBounds"
android:layout_height="0dp"
android:layout_width="0dp"
app:layout_widthPercent="100%"
app:layout_aspectRatio="100%">
</GridLayout>
</android.support.percent.PercentRelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/card_padding_4dp"
android:orientation="vertical">
<TextView
android:id="@+id/album_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Family Photos"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Nếu bất cứ ai có thể nghĩ ra một tiêu đề tốt hơn cho câu hỏi này, hãy chỉnh sửa nó –
Mỗi lần 'onBindViewHolder' được gọi là bạn đang thay thế tất cả hình ảnh từ' GridView'? Tại sao? – rubenlop
Cũng có thể có bất cứ nơi nào từ 1-4 hình ảnh trong bố trí cho bất kỳ mục duy nhất, vì vậy khi các mặt hàng đã tái chế nó sẽ dẫn đến một số nhô ra. Tôi đoán tôi có thể giữ một danh sách các ImageViews và sau đó chỉ cần thiết lập chúng để tầm nhìn biến mất khi chúng được tái chế, nhưng hiệu suất của cuộn là đủ phong nha, vì vậy tôi ít phiền toái hơn vấn đề hiển thị –