Android
Aangepaste weergaven maken
Zoeken…
Aangepaste weergaven maken
Als u een volledig aangepaste weergave nodig hebt, moet u View
(de superklasse van alle Android-weergaven) subklasseeren en uw aangepaste onMeasure(...)
) en tekenen ( onDraw(...)
) onDraw(...)
:
Maak uw aangepaste weergaveskelet: dit is in principe hetzelfde voor elke aangepaste weergave. Hier maken we het skelet voor een aangepaste weergave die een smiley kan tekenen, genaamd
SmileyView
:public class SmileyView extends View { private Paint mCirclePaint; private Paint mEyeAndMouthPaint; private float mCenterX; private float mCenterY; private float mRadius; private RectF mArcBounds = new RectF(); public SmileyView(Context context) { this(context, null, 0); } public SmileyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SmileyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaints(); } private void initPaints() {/* ... */} @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {/* ... */} @Override protected void onDraw(Canvas canvas) {/* ... */} }
Initialiseer uw verven: de
Paint
objecten zijn de penselen van uw virtuele canvas die bepalen hoe uw geometrische objecten worden weergegeven (bijv. Kleur, vulling en lijnstijl, enz.). Hier maken we tweePaint
's, een geel gevulde verf voor de cirkel en een zwarte lijnverf voor de ogen en de mond:private void initPaints() { mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setStyle(Paint.Style.FILL); mCirclePaint.setColor(Color.YELLOW); mEyeAndMouthPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mEyeAndMouthPaint.setStyle(Paint.Style.STROKE); mEyeAndMouthPaint.setStrokeWidth(16 * getResources().getDisplayMetrics().density); mEyeAndMouthPaint.setStrokeCap(Paint.Cap.ROUND); mEyeAndMouthPaint.setColor(Color.BLACK); }
Implementeer uw eigen
onMeasure(...)
-methode: dit is vereist zodat de bovenliggende lay-outs (bijv.FrameLayout
) uw aangepaste weergave correct kunnen uitlijnen. Het biedt een setmeasureSpecs
die u kunt gebruiken om de hoogte en breedte van uw weergave te bepalen. Hier maken we een vierkant door ervoor te zorgen dat de hoogte en breedte hetzelfde zijn:@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = MeasureSpec.getSize(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); int size = Math.min(w, h); setMeasuredDimension(size, size); }
Merk op dat
onMeasure(...)
minstens één aanroep moet bevatten omsetMeasuredDimension(..)
anders crasht uw aangepaste weergave met eenIllegalStateException
.Implementeer uw eigen
onSizeChanged(...)
-methode: hiermee kunt u de huidige hoogte en breedte van uw aangepaste weergaveonSizeChanged(...)
om uw renderingcode correct aan te passen. Hier berekenen we gewoon ons centrum en onze straal:@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCenterX = w / 2f; mCenterY = h / 2f; mRadius = Math.min(w, h) / 2f; }
Implementeer uw eigen
onDraw(...)
-methode: hier implementeert u de daadwerkelijke weergave van uw weergave. Het biedt eenCanvas
object waarop u kunt tekenen (zie de officiëleCanvas
documentatie voor alle beschikbare tekenmethoden).@Override protected void onDraw(Canvas canvas) { // draw face canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint); // draw eyes float eyeRadius = mRadius / 5f; float eyeOffsetX = mRadius / 3f; float eyeOffsetY = mRadius / 3f; canvas.drawCircle(mCenterX - eyeOffsetX, mCenterY - eyeOffsetY, eyeRadius, mEyeAndMouthPaint); canvas.drawCircle(mCenterX + eyeOffsetX, mCenterY - eyeOffsetY, eyeRadius, mEyeAndMouthPaint); // draw mouth float mouthInset = mRadius /3f; mArcBounds.set(mouthInset, mouthInset, mRadius * 2 - mouthInset, mRadius * 2 - mouthInset); canvas.drawArc(mArcBounds, 45f, 90f, false, mEyeAndMouthPaint); }
Voeg uw aangepaste weergave toe aan een lay-out: de aangepaste weergave kan nu worden opgenomen in alle lay-outbestanden die u hebt. Hier wikkelen we het gewoon in een
FrameLayout
:<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.app.SmileyView android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
Houd er rekening mee dat het wordt aanbevolen om uw project te bouwen nadat de weergavecode is voltooid. Zonder het te bouwen, kunt u de weergave niet zien op een voorbeeldscherm in Android Studio.
Nadat je alles hebt samengesteld, zou je na het starten van de activiteit met bovenstaande lay-out moeten worden begroet met het volgende scherm:
Kenmerken toevoegen aan weergaven
Aangepaste weergaven kunnen ook aangepaste attributen bevatten die kunnen worden gebruikt in Android-layoutresourcebestanden. Om attributen aan uw aangepaste weergave toe te voegen, moet u het volgende doen:
Definieer de naam en het type van uw attributen: dit gebeurt in
res/values/attrs.xml
(maak het indien nodig). Het volgende bestand definieert een kleurkenmerk voor de gezichtskleur van onze smiley en een enum-kenmerk voor de uitdrukking van de smiley:<resources> <declare-styleable name="SmileyView"> <attr name="smileyColor" format="color" /> <attr name="smileyExpression" format="enum"> <enum name="happy" value="0"/> <enum name="sad" value="1"/> </attr> </declare-styleable> <!-- attributes for other views --> </resources>
Gebruik uw attributen in uw lay-out: dit kan worden gedaan in alle lay-outbestanden die uw aangepaste weergave gebruiken. Het volgende lay-outbestand maakt een scherm met een vrolijke gele smiley:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" android:layout_width="match_parent"> <com.example.app.SmileyView android:layout_height="56dp" android:layout_width="56dp" app:smileyColor="#ffff00" app:smileyExpression="happy" /> </FrameLayout>
Tip: aangepaste attributen werken niet met de
tools:
voorvoegsel in Android Studio 2.1 en ouder (en mogelijk in toekomstige versies). In dit voorbeeld zou het vervangen vanapp:smileyColor
doortools:smileyColor
ertoe leiden datsmileyColor
niet wordt ingesteld tijdens runtime of tijdens het ontwerp.Lees uw kenmerken: dit gebeurt in uw aangepaste weergavebroncode. Het volgende fragment van
SmileyView
laat zien hoe de attributen kunnen worden geëxtraheerd:public class SmileyView extends View { // ... public SmileyView(Context context) { this(context, null); } public SmileyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SmileyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmileyView, defStyleAttr, 0); mFaceColor = a.getColor(R.styleable.SmileyView_smileyColor, Color.TRANSPARENT); mFaceExpression = a.getInteger(R.styleable.SmileyView_smileyExpression, Expression.HAPPY); // Important: always recycle the TypedArray a.recycle(); // initPaints(); ... } }
(Optioneel) Standaardstijl toevoegen: dit wordt gedaan door een stijl met de standaardwaarden toe te voegen en deze in uw aangepaste weergave te laden. De volgende standaard smileystijl vertegenwoordigt een gelukkige gele:
<!-- styles.xml --> <style name="DefaultSmileyStyle"> <item name="smileyColor">#ffff00</item> <item name="smileyExpression">happy</item> </style>
Die wordt toegepast in onze
SmileyView
door deze toe te voegen als de laatste parameter van de aanroep om teobtainStyledAttributes
(zie code in stap 3):TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmileyView, defStyleAttr, R.style.DefaultSmileyViewStyle);
Merk op dat alle attribuutwaarden die zijn ingesteld in het opgeblazen lay-outbestand (zie code in stap 2) de overeenkomstige waarden van de standaardstijl overschrijven.
(Optioneel) Zorg voor stijlen in thema's: dit wordt gedaan door een nieuw kenmerk voor stijlreferenties toe te voegen dat binnen uw thema's kan worden gebruikt en een stijl voor dat kenmerk aan te bieden. Hier noemen we eenvoudig ons referentiekenmerk
smileyStyle
:<!-- attrs.xml --> <attr name="smileyStyle" format="reference" />
Waar we vervolgens een stijl voor bieden in ons app-thema (hier hergebruiken we gewoon de standaardstijl uit stap 4):
<!-- themes.xml --> <style name="AppTheme" parent="AppBaseTheme"> <item name="smileyStyle">@style/DefaultSmileyStyle</item> </style>
Samengestelde weergave maken
Een samengestelde weergave is een aangepaste ViewGroup
die door de omringende programmacode als een enkele weergave wordt behandeld. Zo'n ViewGroup kan erg handig zijn in DDD- achtig ontwerp, omdat het kan overeenkomen met een aggregaat, in dit voorbeeld een Contact. Het kan overal worden hergebruikt waar contact wordt weergegeven.
Dit betekent dat de omliggende controllercode, een activiteit, fragment of adapter, het gegevensobject eenvoudig aan de weergave kan doorgeven zonder het in een aantal verschillende UI-widgets op te nemen.
Dit maakt hergebruik van code mogelijk en zorgt voor een beter ontwerp volgens de SOLID-principes .
De lay-out XML
Dit is meestal waar je begint. Je hebt een bestaand stukje XML dat je hergebruikt, misschien als een <include/>
. Pak het uit in een apart XML-bestand en verpak de root-tag in een <merge>
-element:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/photo"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true" />
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/photo" />
<TextView
android:id="@+id/phone_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_toLeftOf="@id/photo" />
</merge>
Dit XML-bestand blijft prima werken in de Layout Editor in Android Studio. Je kunt het behandelen als elke andere lay-out.
De samengestelde ViewGroup
Nadat u het XML-bestand hebt, maakt u de aangepaste weergavegroep.
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.ImageView;
import android.widget.TextView;
import myapp.R;
/**
* A compound view to show contacts.
*
* This class can be put into an XML layout or instantiated programmatically, it
* will work correctly either way.
*/
public class ContactView extends RelativeLayout {
// This class extends RelativeLayout because that comes with an automatic
// (MATCH_PARENT, MATCH_PARENT) layout for its child item. You can extend
// the raw android.view.ViewGroup class if you want more control. See the
// note in the layout XML why you wouldn't want to extend a complex view
// such as RelativeLayout.
// 1. Implement superclass constructors.
public ContactView(Context context) {
super(context);
init(context, null);
}
// two extra constructors left out to keep the example shorter
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ContactView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
// 2. Initialize the view by inflating an XML using `this` as parent
private TextView mName;
private TextView mPhoneNumber;
private ImageView mPhoto;
private void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.contact_view, this, true);
mName = (TextView) findViewById(R.id.name);
mPhoneNumber = (TextView) findViewById(R.id.phone_number);
mPhoto = (ImageView) findViewById(R.id.photo);
}
// 3. Define a setter that's expressed in your domain model. This is what the example is
// all about. All controller code can just invoke this setter instead of fiddling with
// lots of strings, visibility options, colors, animations, etc. If you don't use a
// custom view, this code will usually end up in a static helper method (bad) or copies
// of this code will be copy-pasted all over the place (worse).
public void setContact(Contact contact) {
mName.setText(contact.getName());
mPhoneNumber.setText(contact.getPhoneNumber());
if (contact.hasPhoto()) {
mPhoto.setVisibility(View.VISIBLE);
mPhoto.setImageBitmap(contact.getPhoto());
} else {
mPhoto.setVisibility(View.GONE);
}
}
}
Met de methode init(Context, AttributeSet)
leest u aangepaste XML-kenmerken zoals uitgelegd in Kenmerken toevoegen aan weergaven .
Met deze stukken op hun plaats, kunt u het in uw app gebruiken.
Gebruik in XML
Hier is een voorbeeld van fragment_contact_info.xml
dat illustreert hoe je een enkele ContactView bovenaan een lijst met berichten zou plaatsen:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- The compound view becomes like any other view XML element -->
<myapp.ContactView
android:id="@+id/contact"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/message_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
Gebruik in code
Hier is een voorbeeld van RecyclerView.Adapter
die een lijst met contacten toont. Dit voorbeeld illustreert hoeveel schoner de controllercode krijgt wanneer deze volledig vrij is van View-manipulatie.
package myapp;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
public class ContactsAdapter extends RecyclerView.Adapter<ContactsViewHolder> {
private final Context context;
public ContactsAdapter(final Context context) {
this.context = context;
}
@Override
public ContactsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ContactView v = new ContactView(context); // <--- this
return new ContactsViewHolder(v);
}
@Override
public void onBindViewHolder(ContactsViewHolder holder, int position) {
Contact contact = this.getItem(position);
holder.setContact(contact); // <--- this
}
static class ContactsViewHolder extends RecyclerView.ViewHolder {
public ContactsViewHolder(ContactView itemView) {
super(itemView);
}
public void setContact(Contact contact) {
((ContactView) itemView).setContact(contact); // <--- this
}
}
}
CustomView prestatietips
Wijs geen nieuwe objecten toe in onDraw
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(); //Do not allocate here
}
In plaats van tekeningen op canvas te tekenen ...
drawable.setBounds(boundsRect);
drawable.draw(canvas);
Gebruik een bitmap voor sneller tekenen:
canvas.drawBitmap(bitmap, srcRect, boundsRect, paint);
Trek niet de hele weergave opnieuw om slechts een klein deel ervan bij te werken. Teken in plaats daarvan het specifieke gedeelte van de weergave opnieuw.
invalidate(boundToBeRefreshed);
Als uw weergave bezig is met een doorlopende animatie, bijvoorbeeld een wijzerplaat die elke seconde wordt weergegeven, stop dan ten minste de animatie bij onStop()
van de activiteit en start deze opnieuw op onStart()
van de activiteit.
Voer geen berekeningen uit binnen de onDraw
methode van een weergave, u moet in plaats daarvan de tekening voltooien voordat u invalidate()
onDraw
. Door deze techniek te gebruiken, kunt u voorkomen dat het frame in uw weergave valt.
rotaties
De basisbewerkingen van een weergave zijn vertalen, roteren, enz ... Bijna elke ontwikkelaar heeft dit probleem ondervonden wanneer ze bitmap of verlopen gebruiken in hun aangepaste weergave. Als de weergave een geroteerde weergave toont en de bitmap in die aangepaste weergave moet worden geroteerd, zullen velen van ons denken dat deze duur zal zijn. Velen denken dat het roteren van een bitmap erg duur is, omdat je daarvoor de pixelmatrix van de bitmap moet vertalen. Maar de waarheid is dat het niet zo moeilijk is! In plaats van de bitmap te roteren, draait u gewoon het canvas zelf!
// Save the canvas state
int save = canvas.save();
// Rotate the canvas by providing the center point as pivot and angle
canvas.rotate(pivotX, pivotY, angle);
// Draw whatever you want
// Basically whatever you draw here will be drawn as per the angle you rotated the canvas
canvas.drawBitmap(...);
// Now restore your your canvas to its original state
canvas.restore(save);
// Unless canvas is restored to its original state, further draw will also be rotated.
Samengestelde weergave voor SVG / VectorDrawable als drawableRight
Het belangrijkste motief om deze samengestelde weergave te ontwikkelen is, dat apparaten onder de 5.0 geen ondersteuning bieden voor svg in te tekenen in TextView / EditText. Nog een pro is, kunnen we stellen height
en width
van drawableRight
binnen EditText
. Ik heb het van mijn project gescheiden en in een afzonderlijke module gemaakt.
Module naam: custom_edit_drawable (korte naam voor prefix- c_d_e)
"c_d_e_" voorvoegsel dat moet worden gebruikt zodat bronnen van app-modules deze niet per ongeluk kunnen overschrijven. Voorbeeld: "abc" -voorvoegsel wordt door google gebruikt in de ondersteuningsbibliotheek.
build.gradle
dependencies {
compile 'com.android.support:appcompat-v7:25.3.1'
}
gebruik AppCompat> = 23
Layoutbestand: c_e_d_compound_view.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edt_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1"
android:paddingEnd="40dp"
android:paddingLeft="5dp"
android:paddingRight="40dp"
android:paddingStart="5dp" />
<!--make sure you are not using ImageView instead of this-->
<android.support.v7.widget.AppCompatImageView
android:id="@+id/drawbleRight_search"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right|center_vertical"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
</FrameLayout>
Aangepaste kenmerken: attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="EditTextWithDrawable">
<attr name="c_e_d_drawableRightSVG" format="reference" />
<attr name="c_e_d_hint" format="string" />
<attr name="c_e_d_textSize" format="dimension" />
<attr name="c_e_d_textColor" format="color" />
</declare-styleable>
</resources>
Code: EditTextWithDrawable.java
public class EditTextWithDrawable extends FrameLayout {
public AppCompatImageView mDrawableRight;
public EditText mEditText;
public EditTextWithDrawable(Context context) {
super(context);
init(null);
}
public EditTextWithDrawable(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public EditTextWithDrawable(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public EditTextWithDrawable(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
private void init(AttributeSet attrs) {
if (attrs != null && !isInEditMode()) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.c_e_d_compound_view, this, true);
mDrawableRight = (AppCompatImageView) ((FrameLayout) getChildAt(0)).getChildAt(1);
mEditText = (EditText) ((FrameLayout) getChildAt(0)).getChildAt(0);
TypedArray attributeArray = getContext().obtainStyledAttributes(
attrs,
R.styleable.EditTextWithDrawable);
int drawableRes =
attributeArray.getResourceId(
R.styleable.EditTextWithDrawable_c_e_d_drawableRightSVG, -1);
if (drawableRes != -1) {
mDrawableRight.setImageResource(drawableRes);
}
mEditText.setHint(attributeArray.getString(
R.styleable.EditTextWithDrawable_c_e_d_hint));
mEditText.setTextColor(attributeArray.getColor(
R.styleable.EditTextWithDrawable_c_e_d_textColor, Color.BLACK));
int textSize = attributeArray.getDimensionPixelSize(R.styleable.EditTextWithDrawable_c_e_d_textSize, 15);
mEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
android.view.ViewGroup.LayoutParams layoutParams = mDrawableRight.getLayoutParams();
layoutParams.width = (textSize * 3) / 2;
layoutParams.height = (textSize * 3) / 2;
mDrawableRight.setLayoutParams(layoutParams);
attributeArray.recycle();
}
}
}
Voorbeeld: gebruik van bovenstaande weergave
Indeling: activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.customeditdrawable.AppEditTextWithDrawable
android:id="@+id/edt_search_emp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:c_e_d_drawableRightSVG="@drawable/ic_svg_search"
app:c_e_d_hint="@string/hint_search_here"
app:c_e_d_textColor="@color/text_color_dark_on_light_bg"
app:c_e_d_textSize="@dimen/text_size_small" />
</LinearLayout>
Activiteit: MainActivity.java
public class MainActivity extends AppCompatActivity {
EditTextWithDrawable mEditTextWithDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditTextWithDrawable= (EditTextWithDrawable) findViewById(R.id.edt_search_emp);
}
}
Reageren op aanraakgebeurtenissen
Veel aangepaste weergaven moeten gebruikersinteractie accepteren in de vorm van aanraakgebeurtenissen. U kunt toegang krijgen tot aanraakgebeurtenissen door onTouchEvent
overschrijven. Er zijn een aantal acties die u kunt uitfilteren. De belangrijkste zijn
-
ACTION_DOWN
: Dit wordt eenmaal geactiveerd wanneer uw vinger voor het eerst de weergave raakt. -
ACTION_MOVE
: Dit wordt elke keer genoemd als je vinger een beetje over het beeld beweegt. Het wordt vaak genoemd. -
ACTION_UP
: dit is de laatste actie die wordt opgeroepen terwijl u uw vinger van het schermACTION_UP
.
U kunt de volgende methode aan uw weergave toevoegen en vervolgens de log-uitvoer observeren wanneer u uw vinger over uw weergave aanraakt en beweegt.
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.i("CustomView", "onTouchEvent: ACTION_DOWN: x = " + x + ", y = " + y);
break;
case MotionEvent.ACTION_MOVE:
Log.i("CustomView", "onTouchEvent: ACTION_MOVE: x = " + x + ", y = " + y);
break;
case MotionEvent.ACTION_UP:
Log.i("CustomView", "onTouchEvent: ACTION_UP: x = " + x + ", y = " + y);
break;
}
return true;
}
Verder lezen: