android按比例增加坐标图片,Android 在图片的指定位置添加标记

这些天,项目里加了一个功能效果,场景是: 假如有一个家居图片,图片里,有各样的家居用品: 桌子,毛巾,花瓶等等,需要在指定的商品处添加标记,方便用户直接看到商品,点击该标记,可以进入到商品详情页 。实现的效果图如下:

68ae25efb296d2f20f9b305dd36f68ed.gif

要实现如上效果,有两个思路。

思路1,通过addView,在容器(如FrameLayout)的特定位置,添加标记组件,同事在将ImageView页添加进容器中,保证容器的大小和ImageView的大小相同,这样可以确认标记点的位置不会出现错差。

思路2,通过绘制Bitmap,将背景图片和标记点绘制成同一张图片。

比较两种方法,思路2有些不太妥的地方,1是不好实现标记图标的点击事件;2是不太容易扩展,比如标记点不仅仅是一个图片,而是一个弹框组件,有图有文。 所以,考虑再三后,决定选择第一种实现方式。

1. 自定义布局,包含放置标记图标的容器及显示底部图片的ImageView。

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/imgBg"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:adjustViewBounds="true"

android:maxHeight="1000dp"

android:scaleType="centerCrop" />

android:id="@+id/layouPoints"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center" />

2. 自定义组件,便于添加标记图标、加载背景图

import android.content.Context;

import android.graphics.drawable.AnimationDrawable;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.Toast;

import com.bumptech.glide.Glide;

import com.lnyp.imgdots.R;

import com.lnyp.imgdots.bean.PointSimple;

import java.util.ArrayList;

public class ImageLayout extends FrameLayout implements View.OnClickListener {

ArrayList points;

FrameLayout layouPoints;

ImageView imgBg;

Context mContext;

public ImageLayout(Context context) {

this(context, null);

}

public ImageLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ImageLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView(context, attrs);

}

private void initView(Context context, AttributeSet attrs) {

mContext = context;

View imgPointLayout = inflate(context, R.layout.layout_imgview_point, this);

imgBg = (ImageView) imgPointLayout.findViewById(R.id.imgBg);

layouPoints = (FrameLayout) imgPointLayout.findViewById(R.id.layouPoints);

}

public void setImgBg(int width, int height, String imgUrl) {

ViewGroup.LayoutParams lp = imgBg.getLayoutParams();

lp.width = width;

lp.height = height;

imgBg.setLayoutParams(lp);

ViewGroup.LayoutParams lp1 = layouPoints.getLayoutParams();

lp1.width = width;

lp1.height = height;

layouPoints.setLayoutParams(lp1);

Glide.with(mContext).load(imgUrl).asBitmap().into(imgBg);

addPoints(width, height);

}

public void setPoints(ArrayList points) {

this.points = points;

}

private void addPoints(int width, int height) {

layouPoints.removeAllViews();

for (int i = 0; i < points.size(); i++) {

double width_scale = points.get(i).width_scale;

double height_scale = points.get(i).height_scale;

LinearLayout view = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_img_point, this, false);

ImageView imageView = (ImageView) view.findViewById(R.id.imgPoint);

imageView.setTag(i);

AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();

animationDrawable.start();

LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();

layoutParams.leftMargin = (int) (width * width_scale);

layoutParams.topMargin = (int) (height * height_scale);

imageView.setOnClickListener(this);

layouPoints.addView(view, layoutParams);

}

}

@Override

public void onClick(View view) {

int pos = (int) view.getTag();

Toast.makeText(getContext(), "pos : " + pos, Toast.LENGTH_SHORT).show();

}

}  来看看ImageLayout源码,里面有两个重要的方法:

·public void setImgBg(int width, int height, String imgUrl) 该方法主要根据图片的大小,设置标记图容器的大小,然后加载背景图。

·private void addPoints(int width, int height)  该方法主要向记图容器中添加标记图。

3.PointSimple.java

public class PointSimple {

// 标记点相对于横向的宽度的比例

public double width_scale;

// 标记点相对于横向的高度的比例

public double height_scale;

}

4. 添加背景图和标记图

4.1 首先,准备一些测试数据

private void initData() {

imgSimples = new ArrayList<>();

ImgSimple imgSimple1 = new ImgSimple();

imgSimple1.url = "http://o79w6dswy.bkt.clouddn.com/img5.png";

imgSimple1.scale = 1.6f;

ArrayList pointSimples = new ArrayList<>();

PointSimple pointSimple1 = new PointSimple();

pointSimple1.width_scale = 0.36f;

pointSimple1.height_scale = 0.75f;

PointSimple pointSimple2 = new PointSimple();

pointSimple2.width_scale = 0.64f;

pointSimple2.height_scale = 0.5f;

PointSimple pointSimple3 = new PointSimple();

pointSimple3.width_scale = 0.276f;

pointSimple3.height_scale = 0.764f;

PointSimple pointSimple4 = new PointSimple();

pointSimple4.width_scale = 0.638f;

pointSimple4.height_scale = 0.74f;

PointSimple pointSimple5 = new PointSimple();

pointSimple5.width_scale = 0.796f;

pointSimple5.height_scale = 0.526f;

PointSimple pointSimple6 = new PointSimple();

pointSimple6.width_scale = 0.486f;

pointSimple6.height_scale = 0.364f;

pointSimples.add(pointSimple1);

pointSimples.add(pointSimple2);

pointSimples.add(pointSimple3);

pointSimples.add(pointSimple4);

pointSimples.add(pointSimple5);

pointSimples.add(pointSimple6);

imgSimple1.pointSimples = pointSimples;

ImgSimple imgSimple2 = new ImgSimple();

imgSimple2.url = "http://o79w6dswy.bkt.clouddn.com/img3.png";

imgSimple2.scale = 1.6f;

ArrayList pointSimples2 = new ArrayList<>();

PointSimple pointSimple7 = new PointSimple();

pointSimple7.width_scale = 0.36f;

pointSimple7.height_scale = 0.75f;

PointSimple pointSimple8 = new PointSimple();

pointSimple8.width_scale = 0.64f;

pointSimple8.height_scale = 0.5f;

PointSimple pointSimple9 = new PointSimple();

pointSimple9.width_scale = 0.276f;

pointSimple9.height_scale = 0.764f;

pointSimples2.add(pointSimple7);

pointSimples2.add(pointSimple8);

pointSimples2.add(pointSimple9);

imgSimple2.pointSimples = pointSimples2;

ImgSimple imgSimple3 = new ImgSimple();

imgSimple3.url = "http://o79w6dswy.bkt.clouddn.com/421428.jpg";

imgSimple3.scale = 0.75f;

ArrayList pointSimples3 = new ArrayList<>();

PointSimple pointSimple11 = new PointSimple();

pointSimple11.width_scale = 0.1f;

pointSimple11.height_scale = 0.3f;

PointSimple pointSimple12 = new PointSimple();

pointSimple12.width_scale = 0.3f;

pointSimple12.height_scale = 0.5f;

PointSimple pointSimple13 = new PointSimple();

pointSimple13.width_scale = 0.5f;

pointSimple13.height_scale = 0.8f;

pointSimples3.add(pointSimple11);

pointSimples3.add(pointSimple12);

pointSimples3.add(pointSimple13);

imgSimple3.pointSimples = pointSimples3;

imgSimples.add(imgSimple1);

imgSimples.add(imgSimple2);

imgSimples.add(imgSimple3);

}

4.2 加载图片和添加标记物,因为要做可以滑动展示的效果,所以在ViewPager的PagerAdapter中进行功能添加。

import android.app.Activity;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.util.DisplayMetrics;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.LinearLayout;

import com.lnyp.imgdots.R;

import com.lnyp.imgdots.bean.ImgSimple;

import com.lnyp.imgdots.bean.PointSimple;

import com.lnyp.imgdots.view.ImageLayout;

import java.util.ArrayList;

import java.util.List;

public class ImgBrowsePagerAdapter extends PagerAdapter {

List imgSimples;

List views;

Activity mContext;

private int width;

public ImgBrowsePagerAdapter(Activity context, List imgSimples) {

this.mContext = context;

this.imgSimples = imgSimples;

this.views = new ArrayList<>();

DisplayMetrics dm = new DisplayMetrics();

context.getWindowManager().getDefaultDisplay().getMetrics(dm);

width = dm.widthPixels;

}

@Override

public int getCount() { // 获得size

return imgSimples.size();

}

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;

}

@Override

public void destroyItem(ViewGroup container, int position, Object object) {

((ViewPager) container).removeView((View) object);

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

LinearLayout view = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_img_browse, null);

ImageLayout layoutContent = (ImageLayout) view.findViewById(R.id.layoutContent);

try {

String imgUrl = imgSimples.get(position).url;

float scale = imgSimples.get(position).scale;

ArrayList pointSimples = imgSimples.get(position).pointSimples;

layoutContent.setPoints(pointSimples);

int height = (int) (width * scale);

layoutContent.setImgBg(width, height, imgUrl);

} catch (Exception e) {

e.printStackTrace();

}

((ViewPager) container).addView(view);

return view;

}

}  4.3 适配器的布局文件layout_img_browse.xml,其中包含了上方自定义的组件ImageLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center"

android:orientation="vertical">

android:id="@+id/layoutContent"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_centerInParent="true" />

此处,稍微讲下ImgBrowsePagerAdapter的instantiateItem(ViewGroup container, int position)方法,在该方法中,我们根据屏幕的宽度,对图片进行等比缩放,计算出了缩放后图片的大小(height和width), 该height和width也就是我们将要添加标记物所在的容器的大小。

通过加载了布局文件,获取ImageLayout对象; 然后,有了这个对象,及计算出的height和width,我们就可以动态的添加背景图及标记物的位置。

因为图片是经过等比缩放的,而标记物的位置是相对于图片的,所以在相同大小的容器添加标记物,它的位置不会出现偏差。

通过以上几步,便可以实现前面动态图中的功能效果了。

如有疑问或建议,欢迎进QQ群讨论:487786925( Android研发村 )

项目github地址:https://github.com/zuiwuyuan/ImgDots

转载于:https://www..com/hehe520/p/6329934.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值