Android
Benutzerdefinierte Ansichten erstellen
Suche…
Benutzerdefinierte Ansichten erstellen
Wenn Sie eine vollständig angepasste Ansicht benötigen, müssen Sie die Ansicht " View
(die Oberklasse aller Android-Ansichten) unterteilen und Ihre benutzerdefinierten onMeasure(...)
) und Zeichnungsmethoden ( onDraw(...)
) onDraw(...)
:
Erstellen Sie Ihr benutzerdefiniertes Ansichtskelett: Dies ist grundsätzlich für jede benutzerdefinierte Ansicht gleich. Hier erstellen wir das Skelett für eine benutzerdefinierte Ansicht, die einen Smiley namens
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) {/* ... */} }
Initialisieren Sie Ihre Farben: Die
Paint
Objekte sind die Pinsel Ihrer virtuellen Leinwand, die festlegen, wie Ihre geometrischen Objekte (z. B. Farbe, Füll- und Konturenstil usw.) gerendert werden. Hier erstellen wir zweiPaint
, eine gelbe Farbe für den Kreis und eine schwarze Strichfarbe für Augen und Mund: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); }
Implementieren Sie Ihre eigene
onMeasure(...)
-Methode: Dies ist erforderlich, damit die übergeordneten Layouts (z. B.FrameLayout
) Ihre benutzerdefinierte Ansicht richtig ausrichten können. Sie enthält eine Reihe vonmeasureSpecs
, mit deren Hilfe Sie Höhe und Breite Ihrer Ansicht bestimmen können. Hier erstellen wir ein Quadrat, indem wir sicherstellen, dass Höhe und Breite gleich sind:@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); }
Beachten Sie, dass
onMeasure(...)
mindestens einen Aufruf vonsetMeasuredDimension(..)
enthalten muss.setMeasuredDimension(..)
Ihre benutzerdefinierte Ansicht mit einerIllegalStateException
.Implementieren Sie Ihre eigene
onSizeChanged(...)
-Methode: Damit können Sie die aktuelle Höhe und Breite Ihrer benutzerdefinierten Ansicht abrufen, um Ihren Rendering-Code richtig anzupassen. Hier berechnen wir nur unser Zentrum und unseren Radius:@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCenterX = w / 2f; mCenterY = h / 2f; mRadius = Math.min(w, h) / 2f; }
Implementieren Sie Ihre eigene
onDraw(...)
-Methode: Hier implementieren Sie das tatsächliche Rendern Ihrer Ansicht. Es stellt einCanvas
Objekt bereit, auf das SieCanvas
können (alle offiziellen Zeichenmethoden finden Sie in der offiziellenCanvas
Dokumentation).@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); }
Fügen Sie Ihre benutzerdefinierte Ansicht einem Layout hinzu: Die benutzerdefinierte Ansicht kann jetzt in alle vorhandenen Layoutdateien eingefügt werden. Hier wickeln wir es einfach in ein
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>
Beachten Sie, dass es empfohlen wird, Ihr Projekt zu erstellen, nachdem der Ansichtscode abgeschlossen ist. Ohne sie zu erstellen, können Sie die Ansicht auf einem Vorschaubildschirm in Android Studio nicht sehen.
Nachdem Sie alles zusammengestellt haben, sollten Sie nach dem Starten der Aktivität, die das obige Layout enthält, mit dem folgenden Bildschirm begrüßt werden:
Attribute zu Ansichten hinzufügen
Benutzerdefinierte Ansichten können auch benutzerdefinierte Attribute enthalten, die in Android-Layout-Ressourcendateien verwendet werden können. Um Ihrer benutzerdefinierten Ansicht Attribute hinzuzufügen, müssen Sie Folgendes tun:
Definieren Sie den Namen und den Typ Ihrer Attribute: Dies geschieht in
res/values/attrs.xml
(res/values/attrs.xml
erstellen). Die folgende Datei definiert ein Farbattribut für die Gesichtsfarbe unseres Smileys und ein Aufzählungsattribut für den Ausdruck des Smileys:<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>
Verwenden Sie Ihre Attribute in Ihrem Layout: Dies kann in allen Layoutdateien erfolgen, die Ihre benutzerdefinierte Ansicht verwenden. Die folgende Layoutdatei erstellt einen Bildschirm mit einem fröhlichen gelben 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>
Tipp: Benutzerdefinierte Attribute funktionieren nicht mit den
tools:
Präfix in Android Studio 2.1 und älter (und möglicherweise in zukünftigen Versionen). In diesem Beispiel wirdapp:smileyColor
durchtools:smileyColor
,smileyColor
weder zur Laufzeit noch zur Entwurfszeit festgelegt wird.Lesen Sie Ihre Attribute: Dies geschieht in Ihrem benutzerdefinierten Ansichts-Quellcode. Der folgende Ausschnitt von
SmileyView
zeigt, wie die Attribute extrahiert werden können: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(); ... } }
(Optional) Standardstil hinzufügen : Dazu fügen Sie einen Stil mit den Standardwerten hinzu und laden ihn in Ihre benutzerdefinierte Ansicht. Der folgende Standard-Smiley-Stil steht für einen glücklichen gelben Stil:
<!-- styles.xml --> <style name="DefaultSmileyStyle"> <item name="smileyColor">#ffff00</item> <item name="smileyExpression">happy</item> </style>
Welches wird in unserem
SmileyView
angewendet, indem es als letzter Parameter des Aufrufs vonobtainStyledAttributes
(siehe Code in Schritt 3):TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmileyView, defStyleAttr, R.style.DefaultSmileyViewStyle);
Beachten Sie, dass bei Attributwerten, die in der aufgeblähten Layoutdatei festgelegt wurden (siehe Code in Schritt 2), die entsprechenden Werte des Standardstils überschrieben werden.
(Optional) Bereitstellen von Stilen in Designs: Dazu fügen Sie ein neues Stilreferenzattribut hinzu, das in Ihren Designs verwendet werden kann, und stellt einen Stil für dieses Attribut bereit. Hier nennen wir einfach unser Referenzattribut
smileyStyle
:<!-- attrs.xml --> <attr name="smileyStyle" format="reference" />
Für das wir dann einen Stil in unserem App-Theme bereitstellen (hier verwenden wir einfach den Standardstil aus Schritt 4):
<!-- themes.xml --> <style name="AppTheme" parent="AppBaseTheme"> <item name="smileyStyle">@style/DefaultSmileyStyle</item> </style>
Zusammengesetzte Ansicht erstellen
Eine zusammengesetzte Ansicht ist eine benutzerdefinierte ViewGroup
, die vom umgebenden Programmcode als einzelne Ansicht behandelt wird. Eine solche ViewGroup kann im DDD- ähnlichen Design sehr nützlich sein, da sie einem Aggregat, in diesem Beispiel einem Kontakt, entsprechen kann. Sie kann überall dort verwendet werden, wo der Kontakt angezeigt wird.
Dies bedeutet, dass der umgebende Controller-Code, eine Aktivität, ein Fragment oder ein Adapter, das Datenobjekt einfach an die Ansicht übergeben kann, ohne es in einer Reihe verschiedener UI-Widgets aufzuteilen.
Dies erleichtert die Wiederverwendung von Code und sorgt für ein besseres Design gemäß den SOLID-Grundsätzen .
Das Layout XML
Hier fängt man normalerweise an. Sie haben ein vorhandenes Stück XML, das Sie wiederverwenden können, möglicherweise als <include/>
. Extrahieren Sie es in eine separate XML-Datei und umschließen Sie das Root-Tag in einem <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>
Diese XML-Datei funktioniert weiterhin einwandfrei im Layout-Editor von Android Studio. Sie können es wie jedes andere Layout behandeln.
Die zusammengesetzte ViewGroup
Wenn Sie die XML-Datei haben, erstellen Sie die benutzerdefinierte Ansichtsgruppe.
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);
}
}
}
Bei der init(Context, AttributeSet)
Methode init(Context, AttributeSet)
lesen Sie benutzerdefinierte XML-Attribute, wie unter Hinzufügen von Attributen zu Ansichten beschrieben .
Mit diesen Stücken können Sie sie in Ihrer App verwenden.
Verwendung in XML
Hier ein Beispiel für fragment_contact_info.xml
, das veranschaulicht, wie Sie eine einzelne ContactView über eine Liste von Nachrichten setzen:
<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>
Verwendung im Code
Hier ist ein Beispiel für RecyclerView.Adapter
, das eine Liste von Kontakten enthält. Dieses Beispiel zeigt, wie viel sauberer der Controller-Code wird, wenn er völlig frei von View-Manipulationen ist.
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-Leistungstipps
Ordnen Sie keine neuen Objekte in onDraw zu
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(); //Do not allocate here
}
Anstatt Drawables auf Leinwand zu zeichnen ...
drawable.setBounds(boundsRect);
drawable.draw(canvas);
Verwenden Sie eine Bitmap zum schnelleren Zeichnen:
canvas.drawBitmap(bitmap, srcRect, boundsRect, paint);
Zeichnen Sie nicht die gesamte Ansicht neu, um nur einen kleinen Teil der Ansicht zu aktualisieren. Zeichnen Sie stattdessen den bestimmten Teil der Ansicht neu.
invalidate(boundToBeRefreshed);
Wenn Ihre Ansicht eine kontinuierliche Animation tut, zum Beispiel eine Uhr-Gesicht jede Sekunde zeigt, zumindest stoppen Sie die Animation bei onStop()
der Aktivität und starten Sie ihn wieder auf onStart()
der Aktivität.
onDraw
Sie keine Berechnungen innerhalb der onDraw
Methode einer Ansicht durch. Stattdessen sollten Sie die Zeichnung beenden, bevor Sie onDraw
invalidate()
aufrufen. Mit dieser Technik können Sie verhindern, dass Bilder in Ihrer Ansicht verschoben werden.
Drehungen
Die grundlegenden Vorgänge einer Ansicht sind Übersetzen, Drehen usw. ... Fast jeder Entwickler ist mit diesem Problem konfrontiert, wenn er Bitmap oder Farbverläufe in seiner benutzerdefinierten Ansicht verwendet. Wenn in der Ansicht eine gedrehte Ansicht angezeigt wird und die Bitmap in dieser benutzerdefinierten Ansicht gedreht werden muss, glauben viele von uns, dass dies teuer wird. Viele denken, dass das Drehen einer Bitmap sehr teuer ist, weil dafür die Pixelmatrix der Bitmap übersetzt werden muss. Aber die Wahrheit ist, dass es nicht so schwer ist! Anstatt die Bitmap zu drehen, drehen Sie einfach die Leinwand selbst!
// 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.
Zusammengesetzte Ansicht für SVG / VectorDrawable als drawableRight
Hauptmotiv für die Entwicklung dieser zusammengesetzten Ansicht ist, dass unter 5.0 Geräte svg nicht in TextView / EditText drawable unterstützt. Ein weiteres drawableRight
ist, wir können die height
und width
von drawableRight
in EditText
. Ich habe es von meinem Projekt getrennt und in einem separaten Modul erstellt.
Modulname: custom_edit_drawable (Kurzname für Präfix c_d_e)
Präfix "c_d_e_", damit die Ressourcen des App-Moduls nicht versehentlich überschrieben werden. Beispiel: Das Präfix "abc" wird von Google in der Support-Bibliothek verwendet.
build.gradle
dependencies {
compile 'com.android.support:appcompat-v7:25.3.1'
}
Verwenden Sie AppCompat> = 23
Layoutdatei: 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>
Benutzerdefinierte Attribute: 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();
}
}
}
Beispiel: Verwendung der obigen Ansicht
Layout: 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>
Tätigkeit: 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);
}
}
Reagieren auf Berührungsereignisse
Viele benutzerdefinierte Ansichten müssen Benutzerinteraktionen in Form von Berührungsereignissen akzeptieren. Sie können Zugriff auf Berührungsereignisse erhalten, indem Sie onTouchEvent
überschreiben. Es gibt eine Reihe von Aktionen, die Sie herausfiltern können. Die wichtigsten sind
-
ACTION_DOWN
: Dies wird einmal ausgelöst, wenn Ihr Finger die Ansicht zum ersten Mal berührt. -
ACTION_MOVE
: Dies wird jedes Mal aufgerufen, wenn sich Ihr Finger ein wenig über die Ansicht bewegt. Es wird oft aufgerufen. -
ACTION_UP
: Dies ist die letzte Aktion, die aufgerufen wird, wenn Sie Ihren Finger vom Bildschirm nehmen.
Sie können Ihrer Ansicht die folgende Methode hinzufügen und dann die Protokollausgabe beobachten, wenn Sie Ihren Finger berühren und um Ihre Ansicht bewegen.
@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;
}
Lesen Sie weiter: