Drag & Drop auf Pinch-zoom View

  • Antworten:0
knucKles
  • Forum-Beiträge: 33

21.03.2013, 15:43:02 via Website

Hallo Community!

Ich bin gerade dabei, eine Funktion in einer App zu implementieren, bei der ich euren Rat benötige. Und zwar möchte ich aus einem Seitenmenü heraus kleine Marker auf eine Art Karte ziehen. D.h. ich habe einen Gebäudeplan, den ich verschieben und zoomen kann und möchte darauf kleine Marker, wie man sie z.B. von Google Maps kennt, setzen.

Die zoom und scroll Funktionalitäten habe ich mit einer WebView realisiert. Hier ein Teil des Codes:

1public void handlePinchZooming() {
2 WebView webView = (WebView) findViewById(R.id.blueprint_webview);
3 webView.setInitialScale(50);
4 webView.getSettings().setBuiltInZoomControls(true);
5 webView.getSettings().setLoadWithOverviewMode(true);
6 webView.getSettings().setUseWideViewPort(true);
7 webView.loadUrl("file:///android_asset/blueprint_example.jpg");
8}

Das funktioniert so weit auch ganz gut (außer dass die Karte anfangs trotz dem gesetzten initial scale von 50 stets zu groß eingefügt wird).

Für die Drag & Drop Geschichte gibt es eine Klasse, die das Berühren und Ziehen eines Elementes handled und eine für das Droppen und hinzufügen zum darunter liegenden WebView. Hier die beiden Klassen:

1public final class DragDropTouchListener implements View.OnTouchListener {
2 public boolean onTouch(View view, MotionEvent motionEvent) {
3 ImageView marker = (ImageView) findViewById(R.id.marker_printer);
4 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
5 ClipData data = ClipData.newPlainText("", "");
6 View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(marker);
7 marker.startDrag(data, shadowBuilder, marker, 0);
8 marker.setVisibility(View.INVISIBLE);
9 return true;
10 } else {
11 return false;
12 }
13 }
14}

1class DragDropDragListener implements View.OnDragListener {
2 Drawable enterShape = getResources().getDrawable(R.drawable.blueprint_example);
3 Drawable normalShape = getResources().getDrawable(R.drawable.blueprint_example);
4
5 @Override
6 public boolean onDrag(View v, DragEvent event) {
7 int action = event.getAction();
8 switch (event.getAction()) {
9 case DragEvent.ACTION_DRAG_STARTED:
10 // Do nothing
11 break;
12 case DragEvent.ACTION_DRAG_ENTERED:
13 v.setBackgroundDrawable(enterShape);
14 break;
15 case DragEvent.ACTION_DRAG_EXITED:
16 v.setBackgroundDrawable(normalShape);
17 break;
18 case DragEvent.ACTION_DROP:
19 // Dropped, reassign View to ViewGroup
20 View view = (View) event.getLocalState();
21 ViewGroup owner = (ViewGroup) view.getParent();
22 owner.removeView(view);
23 WebView container = (WebView) v;
24 container.addView(view);
25 view.setX(event.getX() - 18); // drop at mouse position plus half of icon width and height
26 view.setY(event.getY() - 18);
27 view.setVisibility(View.VISIBLE);
28 setMarkerOnClickListener(view);
29 break;
30 case DragEvent.ACTION_DRAG_ENDED:
31 v.setBackgroundDrawable(normalShape);
32 default:
33 break;
34 }
35 return true;
36 }
37...
38}

Ich bin mir nicht sicher, ob das auch wichtig für euch zur Analyse ist, aber hier mal der entsprechende Ausschnitt aus meiner XML Layout Datei:

1<WebView
2 android:layout_width="wrap_content"
3 android:layout_height="wrap_content"
4 android:id="@+id/blueprint_webview" android:layout_row="1" android:layout_column="0"
5 android:layout_columnSpan="4" android:layout_gravity="center|fill"/>
6<SlidingDrawer
7 android:layout_width="wrap_content"
8 android:layout_height="match_parent"
9 android:content="@+id/listview_devices"
10 android:handle="@+id/handle" android:id="@+id/slidingDrawer"
11 android:layout_column="3" android:layout_row="1" android:orientation="horizontal"
12 android:layout_gravity="center|left" android:layout_marginLeft="850dp">
13 <RelativeLayout
14 android:id="@+id/listview_devices"
15 android:layout_width="fill_parent"
16 android:layout_height="fill_parent" android:orientation="vertical" android:baselineAligned="true"
17 android:gravity="right" android:measureWithLargestChild="false" android:showDividers="beginning|end"
18 android:background="#000000">
19 <ExpandableListView
20 android:layout_width="wrap_content"
21 android:layout_height="wrap_content"
22 android:id="@+id/expandablelistview_devices"
23 android:background="#000000"/>
24 </RelativeLayout>
25 <Button
26 android:id="@+id/handle"
27 android:layout_width="30dp"
28 android:layout_height="wrap_content"
29 android:text="||" android:background="#000000" android:textStyle="bold" android:typeface="normal"
30 android:textSize="32dp"/>
31</SlidingDrawer>

Um endlich mal zum Punkt zu kommen, hier nun mein Problem:

Wenn ich einen Marker auf die WebView ziehe und loslasse, wird er an einer falschen Position platziert. Diese ist für unterschiedliche Marker auch nie gleich. Also es ist scheinbar nicht nur eine falsche Berechnung des relativen Abstands zum Finger o.ä.. Das nächste Problem ist, dass die Marker ihren absoluten Abstand und die absolute Position im WebView behalten, wenn man zoomt. Beim Bewegen der Karte wandern die Marker schön brav mit, aber beim Zoomen wird alles vermurkst.

Ich würde mich sehr freuen, wenn mir jemand von euch auf die Sprünge helfen kann, wo ich hier was falsch mache und wie ich es evtl. lösen kann. Jede Map App kann das doch auch, also muss es dafür doch eine gängige Lösung geben.

Beste Grüße,
knucKles

Antworten