Ich habe eine Anwendung, in der ich ein Bild in einem ImageView in einem Fragment aus der Aktivität angezeigt anzeigen. Ich möchte auf Berührungsereignisse im ImageView reagieren, indem ich kleine punktförmige Kreise um die Koordinaten des Berührungsereignisses herum zeichne.Effizientes Zeichnen über ein imageView, das sich in einem Fragment als Reaktion auf ein Berührungsereignis befindet
Nach einigen googeln und Lesen implementiert ich den folgenden Code innerhalb der Fragment-Klasse:
public class ImageViewFragment extends Fragment implements View.OnTouchListener
{
private ImageView mImageView;
private Bitmap mBitmap;
private List<Pair<Integer, Integer>> mScribblePointsCoords;
private Paint mPaint;
public interface OnScribbleUpdate
{
void onNewScribblePoint(List<Pair<Integer, Integer>> coordinates);
}
@Override
public boolean onTouch(View v, MotionEvent event)
{
v.onTouchEvent(event);
return true;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mScribblePointsCoords = new ArrayList<>();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.image_view_fragment, container, false);
view.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
int x = (int) event.getX();
int y = (int) event.getY();
mScribblePointsCoords.add(new Pair<>(x, y));
Bitmap tempBitmap = mBitmap.copy(mBitmap.getConfig(), true);
Canvas canvas = new Canvas(tempBitmap);
canvas.drawCircle(x, y, R.dimen.default_scribble_point_radius, mPaint);
mImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));
mBitmap = tempBitmap;
return true;
}
return false;
}
});
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mImageView = view.findViewById(R.id.new_photo_view);
mImageView.setImageBitmap(mBitmap);
return view;
}
@Override
public void onResume()
{
super.onResume();
mImageView.setImageBitmap(mBitmap);
}
public void setImage(Bitmap bmp)
{
mBitmap = bmp.copy(bmp.getConfig(), false);
if(this.isResumed())
{
mImageView.setImageBitmap(mBitmap);
}
}
public void clearScribble()
{
mScribblePointsCoords.clear();
}
public List<Pair<Integer, Integer>> getScribbleCoordinates()
{
return mScribblePointsCoords;
}
}
Edit: image_view_fragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cofproject.tau.android.cof.ImageViewFragment">
<ImageView
android:id="@+id/new_photo_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:srcCompat="@android:color/background_dark"/>
</FrameLayout>
Ende bearbeiten
Nun, das Problem damit ist, dass ich ge t die Gesamtheit des ImageViews wurde durchgehend blau dargestellt (ich habe verschiedene Radiusgrößen für R.dimen.default_scribble_point_radius wie 5, 0,5 und 0,1 ausprobiert, aber ohne Erfolg).
Vorher:
Nach:
Ich habe eine dreiteilige Frage:
Was mache ich falsch und wie kann ich ein einfacher Punkt-ähnlicher Kreis, anstatt zu haben Der gesamte ImageView wird blau.
Ich denke, dass meine
onTouch(View v, MotionEvent event)
Methode sehr ineffizient ist, da es die Bitmap für jeden hinzugefügten Punkt neu zeichnen musste, und ich mich fragte, ob es einen effizienten Weg gibt, die gleiche Sache zu erreichen.Würde eine transparente Ansicht von sowesort, auf der die Zeichnung stattfinden wird, mir Schwierigkeiten ersparen, und wenn ja, wie kann so etwas erreicht werden?
Ihre Meinung und Anleitung wird sehr geschätzt.
Leider habe ich keine Ahnung, warum Sie einen blauen Image bekommen. Aber mein Ansatz scheint nicht in dieses Problem zu laufen (vielleicht weil ich nicht versuche, Bitmaps zu behandeln), zumindest auf Emulatoren mit Lollipop (Android 5) .und Nougat (Android 7) – 0X0nosugar
Danke für die detaillierte Antwort. Ich erhalte diese Warnung: Benutzerdefinierte Ansicht '' DottedView'' hat 'setOnTouchListener' aufgerufen, überschreibt aber' performClick' nicht Sollte ich damit beschäftigt sein? –
Ich denke, die zwei Antworten auf [diese SO-Post] (https://stackoverflow.com/questions/27462468/custom-view-overrides-ontouchevent-but-not-performclick/32995457) decken es ziemlich gut ab: override performClick() wenn Sie erwarten, dass eine Komponente (z. B. Accessibility Services) sie aufruft. Sonst wird es nicht notwendig sein. – 0X0nosugar