Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 在圖片的指定位置添加標記

Android 在圖片的指定位置添加標記

編輯:關於Android編程

這些天,項目裡加了一個功能效果,場景是: 假如有一個家居圖片,圖片裡,有各樣的家居用品: 桌子,毛巾,花瓶等等,需要在指定的商品處添加標記,方便用戶直接看到商品,點擊該標記,可以進入到商品詳情頁 。實現的效果圖如下:

\

要實現如上效果,有兩個思路。

思路1,通過addView,在容器(如FrameLayout)的特定位置,添加標記組件,同事在將ImageView頁添加進容器中,保證容器的大小和ImageView的大小相同,這樣可以確認標記點的位置不會出現錯差。

思路2,通過繪制Bitmap,將背景圖片和標記點繪制成同一張圖片。

比較兩種方法,思路2有些不太妥的地方,1是不好實現標記圖標的點擊事件;2是不太容易擴展,比如標記點不僅僅是一個圖片,而是一個彈框組件,有圖有文。 所以,考慮再三後,決定選擇第一種實現方式。

 

1. 自定義布局,包含放置標記圖標的容器及顯示底部圖片的ImageView。

 


<framelayout android:layout_height="wrap_content" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">

    

    <framelayout android:id="@+id/layouPoints" android:layout_gravity="center" android:layout_height="wrap_content" android:layout_width="match_parent">

</framelayout></framelayout>

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



    

 

 

此處,稍微講下ImgBrowsePagerAdapter的instantiateItem(ViewGroup container, int position)方法,在該方法中,我們根據屏幕的寬度,對圖片進行等比縮放,計算出了縮放後圖片的大小(height和width), 該height和width也就是我們將要添加標記物所在的容器的大小。

通過加載了布局文件,獲取ImageLayout對象; 然後,有了這個對象,及計算出的height和width,我們就可以動態的添加背景圖及標記物的位置。

因為圖片是經過等比縮放的,而標記物的位置是相對於圖片的,所以在相同大小的容器添加標記物,它的位置不會出現偏差。

 

通過以上幾步,便可以實現前面動態圖中的功能效果了。

如有疑問或建議,歡迎進QQ群討論:487786925( Android研發村 )

 

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

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved