居中裁剪图像,缓慢缩小效果。

huangapple go评论142阅读模式
英文:

CenterCrop image with slow zoom out

问题

public class HorizontalGalleryRecyclerViewAdapter extends RecyclerView.Adapter<HorizontalGalleryRecyclerViewAdapter.MyViewHolder> {

    private Context mContext;
    private ArrayList<ImageItems> arrayList;
    public long Last_position;

    private HorizontalGalleryRecyclerViewAdapter.onItemCLickListener mListener;

    public interface onItemCLickListener {
        void onItemClick(int mPosition);
    }

    public void setOnItemClickListener(HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
        mListener = listener;
    }

    public HorizontalGalleryRecyclerViewAdapter(Context context, ArrayList<ImageItems> arrayList) {
        this.mContext = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder((LayoutInflater.from(mContext).inflate(R.layout.horizontal_gallery_recycleriew_item, parent, false)), mListener);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Glide.with(mContext)
          .load(arrayList.get(position).ImagePath)
          .placeholder(R.drawable.background_gallery_placeholder)
          .error(R.drawable.background_gallery_placeholder)
          .thumbnail(0.5f).into(holder.img);
        Last_position = position;
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public RoundedImageView img;

        public MyViewHolder(View view, final HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
            super(view);

            img = view.findViewById(R.id.horizontal_img);
            img.setScaleX(1.1f);
            img.setScaleY(1.1f);
            img.animate().setDuration(3000).setStartDelay(1000)
                .setInterpolator(new AccelerateDecelerateInterpolator())
                .scaleX(1).scaleY(1).start();

            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (listener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            listener.onItemClick(getAdapterPosition());
                        }
                    }
                }
            });
        }
    }
}
英文:

I have created a horizontal recyclerview that shows images taken by a user. These images are center cropped and are displayed using Glide. How can I achieve a slow zoom out while the user is viewing the displayed image.

Please refer to this as an example:
https://dribbble.com/shots/8582397-Nomad-iOS-UI-Kit-Favorite-Places

UPDATE:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

public class HorizontalGalleryRecyclerViewAdapter extends RecyclerView.Adapter &lt; HorizontalGalleryRecyclerViewAdapter.MyViewHolder &gt; {
private Context mContext;
private ArrayList &lt; ImageItems &gt; arrayList;
public long Last_position;
private HorizontalGalleryRecyclerViewAdapter.onItemCLickListener mListener;
public interface onItemCLickListener {
void onItemClick(int mPosition);
}
public void setOnItemClickListener(HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
mListener = listener;
}
public HorizontalGalleryRecyclerViewAdapter(Context context, ArrayList &lt; ImageItems &gt; arrayList) {
this.mContext = context;
this.arrayList = arrayList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyViewHolder((LayoutInflater.from(mContext).inflate(R.layout.horizontal_gallery_recycleriew_item, parent, false)), mListener);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Glide.with(mContext)
.load(arrayList.get(position).ImagePath)
.placeholder(R.drawable.background_gallery_placeholder)
.error(R.drawable.background_gallery_placeholder)
.thumbnail(0.5 f).into(holder.img);
Last_position = position;
}
@Override
public int getItemCount() {
return arrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public RoundedImageView img;
public MyViewHolder(View view, final HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
super(view);
img = view.findViewById(R.id.horizontal_img);
img.setScaleX(1.1 f);
img.setScaleY(1.1 f);
img.animate().setDuration(3 _000).setStartDelay(1 _000)
.setInterpolator(new AccelerateDecelerateInterpolator())
.scaleX(1).scaleY(1).start();
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(getAdapterPosition());
}
}
}
});
}
}
}

<!-- end snippet -->

答案1

得分: 1

这个效果可以通过缩小图像来实现。我创建了一个小的演示,没有使用RecyclerView,只是作为一个展示,所以当一个视图被回收时,不要忘记调用view.animate().cancel()

为了能够缩小图像,我首先将其放大,然后进行缩小动画。

public class MainActivity extends AppCompatActivity {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View view = findViewById(R.id.image);
        view.setScaleX(1.1f);
        view.setScaleY(1.1f);
        view.animate().setDuration(3_000).setStartDelay(1_000)
                .setInterpolator(new AccelerateDecelerateInterpolator())
                .scaleX(1).scaleY(1).start();
    }
}

在这个示例中,我选择了android:scaleType="centerCrop",但是当你使用Glide进行操作时,你应该能够达到相同的效果。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/image" />
</FrameLayout>

为了在你的实现中实现缩放效果,你应该在每次绑定时设置初始缩放。

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    holder.img.setScaleX(1.1f);
    holder.img.setScaleY(1.1f);
    Glide.with(mContext)
        .load(arrayList.get(position).ImagePath)
        .placeholder(R.drawable.background_gallery_placeholder)
        .error(R.drawable.background_gallery_placeholder)
        .thumbnail(0.5f).into(holder.img);
}

ViewHolder 本身只应该包含查找视图的逻辑。

public static class MyViewHolder extends RecyclerView.ViewHolder {
    public RoundedImageView img;

    public MyViewHolder(View view, final HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
        super(view);
        img = view.findViewById(R.id.horizontal_img);
        view.setOnClickListener(...);
    }
}

棘手的部分是实际启动动画,因为当前的查看状态不是适配器的一部分。你需要从外部提供它。然后,你可以通过 notifyItemChanged(int,Object) 的负载来提供信息,并在 onBindViewHolder(VH,int,List) 中处理它。但是最终,对于你的用例,onViewAttachedToWindow(VH) 可能已经足够了。

private void startAnimation(VH viewHolder, long duration, long delay) {
    viewHolder.img.animate()
        .setDuration(duration).setStartDelay(delay)
        .setInterpolator(new AccelerateDecelerateInterpolator())
        .scaleX(1).scaleY(1).start();
}
英文:

This effect could be achieved by scaling down the image. I created a small demo without a RecyclerView as a showcase, so don't forget to call view.animate().cancel() when a view gets recycled.

To be able to scale down the image, I scaled it up first. Then I animated the downscale.

public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.image);
view.setScaleX(1.1f);
view.setScaleY(1.1f);
view.animate().setDuration(3_000).setStartDelay(1_000)
.setInterpolator(new AccelerateDecelerateInterpolator())
.scaleX(1).scaleY(1).start();
}
}

I chose android:scaleType=&quot;centerCrop&quot; in this example, but you should be able to achieve the same when you do the operation with Glide.

&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
android:padding=&quot;16dp&quot;&gt;
&lt;ImageView
android:id=&quot;@+id/image&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
android:scaleType=&quot;centerCrop&quot;
android:src=&quot;@drawable/image&quot; /&gt;
&lt;/FrameLayout&gt;

To achieve the scaling with your implementation, you should set the initial scale with every binding.

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.img.setScaleX(1.1 f);
holder.img.setScaleY(1.1 f);
Glide.with(mContext)
.load(arrayList.get(position).ImagePath)
.placeholder(R.drawable.background_gallery_placeholder)
.error(R.drawable.background_gallery_placeholder)
.thumbnail(0.5 f).into(holder.img);
}

The ViewHolder itself should only contain the logic for finding the view.

public static class MyViewHolder extends RecyclerView.ViewHolder {
public RoundedImageView img;
public MyViewHolder(View view, final HorizontalGalleryRecyclerViewAdapter.onItemCLickListener listener) {
super(view);
img = view.findViewById(R.id.horizontal_img);
view.setOnClickListener(...);
}
}

The tricky part is to actually start the animation, since the current viewing state is not part of the adapter. You'd have to provide it from outside. You could then provide the information with the payload of notifyItemChanged(int,Object) and handle it in onBindViewHolder(VH,int,List) instead. But eventually onViewAttachedToWindow(VH) could be sufficient for your usecase.

private void startAnimation(VH viewHolder, long duration, long delay) {
viewHolder.img.animate()
.setDuration(duration).setStartDelay(delay)
.setInterpolator(new AccelerateDecelerateInterpolator())
.scaleX(1).scaleY(1).start();
}

huangapple
  • 本文由 发表于 2020年7月24日 02:43:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63061084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定