2016-11-01 10 views
0

私のアプリケーションで「サブサンプリングスケール画像ビュー」を使用しています。ユーザーが長いクリックをしたときにマーカーピンをPinViewに動的に追加したいと思います。マーカーピンは、クリックされた位置に現れます。サブサンプリングスケール画像ビューを使用してタッチ位置にマーカーピンを追加する

長いクリック後に間違った位置にマーカーピンが表示されることがありました。ここに私の断片のonCreateView方法は次のとおりです。

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    pinCounter=0; 

    View rootView = inflater.inflate(R.layout.fragment_edit_plan, container, false); 
    src = getArguments().getString("src"); 
    imageView = (PinView)rootView.findViewById(R.id.imageView); 

    imageView.setImage(ImageSource.uri(src)); 
    imageView.isLongClickable(); 
    imageView.isClickable(); 
    imageView.hasOnClickListeners(); 

    MapPins = new ArrayList(); 
    imageView.setPins(MapPins); 

    imageView.setOnLongClickListener(this); 
    imageView.setOnTouchListener(this); 

    return rootView; 
} 

リスナー-方法:

@Override 
public boolean onLongClick(View view) { 
    if (view.getId() == R.id.imageView) { 
     Toast.makeText(getActivity(), "Long clicked "+lastKnownX+" "+lastKnownY, Toast.LENGTH_SHORT).show(); 
     Log.d("EditPlanFragment","Scale "+imageView.getScale()); 
     MapPins.add(new MapPin(lastKnownX,lastKnownY,pinCounter)); 
     imageView.setPins(MapPins); 

     imageView.post(new Runnable(){ 
      public void run(){ 
       imageView.getRootView().postInvalidate(); 
      } 
     }); 

     return true; 
    } 
    return false; 
} 

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    if (v.getId()== R.id.imageView && event.getAction() == MotionEvent.ACTION_DOWN){ 
     lastKnownX= event.getX(); 
     lastKnownY= event.getY(); 
    } 
    return false; 
} 

私のXML-ファイル:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:id="@+id/content" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingTop="50dp" 
> 

<com.example.viktoriabock.phoenixversion1.PinView 
    android:id="@+id/imageView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:longClickable="true" 

    /> 

そしてPinView-クラス:

public class PinView extends SubsamplingScaleImageView { 

    private PointF sPin; 

    ArrayList<MapPin> mapPins; 
    ArrayList<DrawPin> drawnPins; 
    Context context; 
    String tag = getClass().getSimpleName(); 

    public PinView(Context context) { 
     this(context, null); 
     this.context = context; 
    } 

    public PinView(Context context, AttributeSet attr) { 
     super(context, attr); 
     this.context = context; 
     initialise(); 
    } 

    public void setPins(ArrayList<MapPin> mapPins) { 
     this.mapPins = mapPins; 
     initialise(); 
     invalidate(); 
    } 

    public void setPin(PointF pin) { 
     this.sPin = pin; 
    } 

    public PointF getPin() { 
     return sPin; 
    } 

    private void initialise() { 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     // Don't draw pin before image is ready so it doesn't move around during  setup. 
     if (!isReady()) { 
      return; 
     } 

     drawnPins = new ArrayList<>(); 

     Paint paint = new Paint(); 
     paint.setAntiAlias(true); 
     float density = getResources().getDisplayMetrics().densityDpi; 


     for (int i = 0; i < mapPins.size(); i++) { 
      MapPin mPin = mapPins.get(i); 
      //Bitmap bmpPin = Utils.getBitmapFromAsset(context, mPin.getPinImgSrc()); 
      Bitmap bmpPin = BitmapFactory.decodeResource(this.getResources(), R.drawable.pushpin_blue); 

      float w = (density/420f) * bmpPin.getWidth(); 
      float h = (density/420f) * bmpPin.getHeight(); 
      bmpPin = Bitmap.createScaledBitmap(bmpPin, (int) w, (int) h, true); 

      PointF vPin = sourceToViewCoord(mPin.getPoint()); 
      //in my case value of point are at center point of pin image, so we need to adjust it here 

      float vX = vPin.x - (bmpPin.getWidth()/2); 
      float vY = vPin.y - bmpPin.getHeight(); 

      canvas.drawBitmap(bmpPin, vX, vY, paint); 

      //add added pin to an Array list to get touched pin 
      DrawPin dPin = new DrawPin(); 
      dPin.setStartX(mPin.getX() - w/2); 
      dPin.setEndX(mPin.getX() + w/2); 
      dPin.setStartY(mPin.getY() - h/2); 
      dPin.setEndY(mPin.getY() + h/2); 
      dPin.setId(mPin.getId()); 
      drawnPins.add(dPin); 
     } 
    } 

    public int getPinIdByPoint(PointF point) { 
     for (int i = drawnPins.size() - 1; i >= 0; i--) { 
      DrawPin dPin = drawnPins.get(i); 
      if (point.x >= dPin.getStartX() && point.x <= dPin.getEndX()) { 
       if (point.y >= dPin.getStartY() && point.y <= dPin.getEndY()) { 
        return dPin.getId(); 
       } 
      } 
     } 
     return -1; //negative no means no pin selected 
    } 
} 

答えて

0

あなたは長押しの画面座標を収集しています。カスタムビューでは、ソース座標から画面座標に変換しています。ビューのviewToSourceCoordメソッドを使用して、タップイベントを取得したときにイベント座標をソース座標に変換する必要があります。

lastKnownの値を使用するより簡単な方法は、GestureDetectorを使用することです。

長押しジェスチャ検出器の完全な動作例については、AdvancedEventHandlingActivity sample classを参照してください。

関連する問題