Vis*_*ale 12 android android-custom-view android-canvas
我需要创建一系列同心椭圆(环),并需要在这些椭圆的圆周上放置用户图标.见下图.

直到现在我在画布上绘制了3个椭圆同心圆并放置了用户图标.我需要用户图标可以跨越环.
请提供实施方法.
由于看起来你已经在戒指的圆周上放置了图标,我假设你知道如何进行数学计算[但是请参见编辑]以确定沿圆周的点并询问拖放.
您可能希望使用拖放方法实现图标移动.假设您将环保持为单个图像,那么您将只有一个放置目标.然后,您需要以数学方式分析掉落点[请参阅编辑](通过确定其像素颜色)以确定图标被放入哪个环.如果为环创建单独的视图,则每个视图都可以是其自己的放置点.(你可能需要最终弄清楚如何在每个环中重新分配图标,但这是一个不同的问题.)
下面是一些代码,它显示了使用单个视图组(您将显示环形图像)上的单个图像图标来处理拖放的最小方法.
package com.example.dragexample;
import android.app.Activity;
import android.content.ClipData;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity {
static final String TAG = "DragActivity";
ImageView icon = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.rings).setOnDragListener(new OnDragListener() {
@Override
public boolean onDrag(View vw, DragEvent event) {
if (event.getAction() == DragEvent.ACTION_DROP) {
// Drop the icon and redisplay it:
icon.setX(event.getX());
icon.setY(event.getY());
icon.setVisibility(View.VISIBLE);
// Analyze the drop point mathematically (or perhaps get its pixel color)
// to determine which ring the icon has been dragged into and then take
// appropriate action.
int destRing = determineDestinationRing(event.getX(), event.getY());
}
return true;
}
});
icon = (ImageView) findViewById(R.id.icon);
icon.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View vw, MotionEvent event) {
Log.v(TAG, "Touch event " + event.getAction());
if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
Log.v(TAG, "Starting drag");
// Set up clip data (empty) and drag shadow objects and start dragging:
ClipData cd = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(vw);
vw.startDrag(cd, shadowBuilder, vw, 0);
vw.setVisibility(View.INVISIBLE);
}
return true;
}
});
}
public void resetImage(View vw) {
Log.v(TAG, "Resetting image position");
icon.setX(0f);
icon.setY(0f);
icon.setVisibility(View.VISIBLE);
}
Run Code Online (Sandbox Code Playgroud)
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rings"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="resetImage" >
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
为了在数学上确定图标被放入哪个环,您可以使用类似下面的内容,它使用轴的硬编码尺寸循环执行椭圆的标准公式.请注意,如果在最里面的"我"环中放置了一个图标,则会返回零.此外,这种方法在实践中将更具挑战性,因为在呈现布局时可能会调整屏幕上的铃声大小.在这种情况下,轴的最终尺寸需要在运行时确定.
// Axis values must be ascending order; ring 0 is 'me';
float a[] = {50, 100, 150, 200};
float b[] = {100, 200, 300, 400};
public int determineDestinationRing(float x, float y) {
// Check for inclusion within each ring:
for (int i = 0; i < a.length; i++) {
if (((x * x) / (a[i] * a[i]) + (y * y) / (b[i] * b[i])) <= 1)
return i;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
646 次 |
| 最近记录: |