English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Zusammenfassung der drei Implementierungsmethoden von Android Custom View

In mehreren Projekten des Abschlussprojekts wurden benutzerdefinierte Steuerelemente verwendet, und ich habe immer vor, die Implementierungsmethoden der benutzerdefinierten Steuerelemente zusammenzufassen. Heute werde ich dies tun. Zuvor habe ich einige Artikel über benutzerdefinierte Views von dem Blog des Meisters Guo Lin gelesen und habe viel gelernt. In diesem Artikel werde ich einige Inhalte aus diesen Artikeln zitieren.

Zusammenfassend lässt sich sagen, dass die Implementierung benutzerdefinierter Steuerelemente in drei Arten erfolgt: kombinierte Steuerelemente, selbstgezeichnete Steuerelemente und vererbte Steuerelemente. Nachfolgend werde ich diese drei Arten im Detail vorstellen.

(1) Kombinierte Steuerelemente

Kombinierte Steuerelemente, wie der Name schon sagt, sind kleine Steuerelemente, die zu einem neuen Steuerelement kombiniert werden. Diese kleinen Steuerelemente sind oft vorgegebene Steuerelemente. Zum Beispiel verwenden viele Anwendungen die Titelleiste, die in der Tat kombinierte Steuerelemente sind. Nachfolgend werde ich die Verwendung von kombinierten Steuerelementen erläutern, indem ich eine einfache benutzerdefinierte Titelleiste erstelle.

1Erstellen Sie ein neues Android-Projekt und erstellen Sie eine benutzerdefinierte Layout-Datei für die Titelzeile title_bar.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="#0000ff" >
  <Button
    android:id="@"+id/left_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_margin="5dp"
    android:background="@drawable/background1_64" />
  <TextView
    android:id="@"+id/title_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="这是标题"
    android:textColor="#ffffff"
    android:textSize="20sp" />
</RelativeLayout>

可见这个标题栏控件还是比较简单的,其中在左边有一个返回按钮,背景是一张事先准备好的图片back1_64.png,标题栏中间是标题文字。

2、创建一个类TitleView,继承自RelativeLayout:

public class TitleView extends RelativeLayout {
  // 返回按钮控件
  private Button mLeftBtn;
  // 标题Tv
  private TextView mTitleTv;
  public TitleView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // 加载布局
    LayoutInflater.from(context).inflate(R.layout.title_bar, this);
    // 获取控件
    mLeftBtn = (Button) findViewById(R.id.left_btn);
    mTitleTv = (TextView) findViewById(R.id.title_tv);
  }
  // 为左侧返回按钮添加自定义点击事件
  public void setLeftButtonListener(OnClickListener listener) {
    mLeftBtn.setOnClickListener(listener);
  }
  // 设置标题的方法
  public void setTitleText(String title) {
    mTitleTv.setText(title);
  }
}

在TitleView中主要是为自定义的标题栏加载了布局,为返回按钮添加事件监听方法,并提供了设置标题文本的方法。

3、在activity_main.xml中引入自定义的标题栏:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
  android:id="@"+id/main_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <com.example.test.TitleView
    android:id="@"+id/title_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
  </com.example.test.TitleView>
</LinearLayout>

4、在MainActivity中获取自定义的标题栏,并且为返回按钮添加自定义点击事件:

private TitleView mTitleBar;
     mTitleBar = (TitleView) findViewById(R.id.title_bar);
    mTitleBar.setLeftButtonListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        Toast.makeText(MainActivity.this, "Wurde auf den Zurück-Button geklickt", Toast.LENGTH_SHORT)
            .show();
        finish();
      }
    });

5、Laufende Ergebnisse wie folgt:

   

So wurde eine benutzerdefinierte Titelleiste auf kombinierte Weise implementiert. Tatsächlich können durch zusätzliche Kombinationen noch komplexere benutzerdefinierte Steuerelemente wie benutzerdefinierte Suchleisten erstellt werden.

 (Zwei) Selbstgezeichnetes Steuerelement

Alle selbstgezeichneten Inhalte des Steuerelements werden selbst gezeichnet und im onDraw-Methode des Views abgeschlossen. Hier wird ein einfacher Zähler implementiert, bei jedem Klick auf das Steuerelement wird der Zählerwert erhöht.1und zeige es an.

1、Erstelle die Klasse CounterView, die von View erbt und das Interface OnClickListener implementiert:

public class CounterView extends View implements OnClickListener {
  // Definiere den Stift
  private Paint mPaint;
  // Wird verwendet, um die Breite und Höhe des Textes zu erhalten
  private Rect mBounds;
  // Zählerwert, jeder Klick auf dieses Steuerelement erhöht seinen Wert1
  private int mCount;
  public CounterView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // Initialisiere den Stift und Rect
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mBounds = new Rect();
    // Klickereignis dieses Steuerelements
    setOnClickListener(this);
  }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mPaint.setColor(Color.BLUE);
    // Zeichne einen mit blauer Farbe gefüllten Rechteck
    canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
    mPaint.setColor(Color.YELLOW);
    mPaint.setTextSize(50);
    String text = String.valueOf(mCount);
    // Gewinnen Sie die Breite und Höhe des Textes
    mPaint.getTextBounds(text, 0, text.length(), mBounds);
    float textWidth = mBounds.width();
    float textHeight = mBounds.height();
    // Zeichen Sie einen String
    canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2
        + textHeight / 2, mPaint);
  }
  @Override
  public void onClick(View v) {
    mCount ++;
    // Neuzeichnen
    invalidate();
  }
}

2、integrieren Sie das benutzerdefinierte Layout in activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
  android:id="@"+id/main_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <com.example.test.CounterView
    android:id="@"+id/counter_view"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_gravity="center_horizontal|top"
    android:layout_margin="20dp" />
</LinearLayout>

3、Laufende Ergebnisse wie folgt:

(三)Erben von Steuereinheiten

Das bedeutet, eine bestehende Steuereinheit zu erben, eine neue Steuereinheit zu erstellen, die Eigenschaften des ererbten Überkontrollers beibehält und auch neue Eigenschaften einführen kann. Nachfolgend wird die Implementierung eines CustomListView vorgestellt, der das laterale Streichen und Löschen von Listenelementen unterstützt.

1、erstellen Sie die Layout-Datei delete_btn.xml für den Löschknopf, die nach dem lateralen Streichen eines Listenelements angezeigt wird:

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="#FF0000"
  android:padding="5dp"
  android:text="Löschen"
  android:textColor="#FFFFFF"
  android:textSize="16sp" >
</Button>

2、erstellen Sie die Klasse CustomListView, die von ListView abgeleitet ist und die Schnittstellen OnTouchListener und OnGestureListener implementiert:

public class CustomListView extends ListView implements OnTouchListener,
    OnGestureListener {
  // Gestur-Erkennungsdetektor
  private GestureDetector mGestureDetector;
  // Löschereignis-Abhörer
  public interface OnDeleteListener {
    void onDelete(int index);
  }
  private OnDeleteListener mOnDeleteListener;
  // Löschknopf
  private View mDeleteBtn;
  // Layout des Listenelements
  private ViewGroup mItemLayout;
  // Gewähltes Listenelement
  private int mSelectedItem;
  // Ob der aktuelle Löschknopf angezeigt wird
  private boolean isDeleteShown;
  public CustomListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // Geste-Erkennungsobjekt erstellen
    mGestureDetector = new GestureDetector(getContext(), this);
    // onTouch-Ereignis überwachen
    setOnTouchListener(this);
  }
  // Löschereignis abonnieren
  public void setOnDeleteListener(OnDeleteListener listener) {
    mOnDeleteListener = listener;
  }
  // Berührungserkennungsereignis
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if (isDeleteShown) {
      hideDelete();
      return false;
    } else {
      return mGestureDetector.onTouchEvent(event);
    }
  }
  @Override
  public boolean onDown(MotionEvent e) {
    if (!isDeleteShown) {
      mSelectedItem = pointToPosition((int) e.getX(), (int) e.getY());
    }
    return false;
  }
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e}}2, float velocityX,
      float velocityY) {
    // Wenn der aktuelle Löschknopf nicht angezeigt wird und die Geschwindigkeit der Schwenkbewegung in der X-Richtung schneller als die in der Y-Richtung ist
    if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {
      mDeleteBtn = LayoutInflater.from(getContext()).inflate(
          R.layout.delete_btn, null);
      mDeleteBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
          mItemLayout.removeView(mDeleteBtn);
          mDeleteBtn = null;
          isDeleteShown = false;
          mOnDeleteListener.onDelete(mSelectedItem);
        }
      });
      mItemLayout = (ViewGroup) getChildAt(mSelectedItem)
          - getFirstVisiblePosition());
      RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
          LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      params.addRule(RelativeLayout.CENTER_VERTICAL);
      mItemLayout.addView(mDeleteBtn, params);
      isDeleteShown = true;
    }
    return false;
  }
  // 隐藏删除按钮
  public void hideDelete() {
    mItemLayout.removeView(mDeleteBtn);
    mDeleteBtn = null;
    isDeleteShown = false;
  }
  public boolean isDeleteShown() {
    return isDeleteShown;
  }
  /**
   * 后面几个方法本例中没有使用
   */
  @Override
  public void onShowPress(MotionEvent e) {
  }
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
    return false;
  }
  @Override
  public boolean onScroll(MotionEvent e)1, MotionEvent e}}2, float distanceX,
      float distanceY) {
    return false;
  }
  @Override
  public void onLongPress(MotionEvent e) {
  }
}

3、定义列表项布局custom_listview_item.xml,它的结构很简单,只包含了一个TextView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:descendantFocusability="blocksDescendants" >
  <TextView
    android:id="@"+id/content_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_margin="30dp"
    android:gravity="center_vertical|left" />
</RelativeLayout>

4、定义适配器类CustomListViewAdapter,继承自ArrayAdapter<String>:

public class CustomListViewAdapter extends ArrayAdapter<String> {
  public CustomListViewAdapter(Context context, int textViewResourceId,
      List<String> objects) {
    super(context, textViewResourceId, objects);
  }
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View view;
    if (convertView == null) {
      view = LayoutInflater.from(getContext()).inflate(
          R.layout.custom_listview_item, null);
    } else {
      view = convertView;
    }
    TextView contentTv = (TextView) view.findViewById(R.id.content_tv);
    contentTv.setText(getItem(position));
    return view;
  }
}

5、in activity_main.xml den benutzerdefinierten ListView einbinden:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
  android:id="@"+id/main_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <com.example.test.CustomListView
    android:id="@"+id/custom_lv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
</LinearLayout>

6、in MainActivity die Liste initialisieren, den Klickereignis der Liste und andere Bearbeitungen einrichten:

public class MainActivity extends Activity {
  // benutzerdefinierte Lv
  private CustomListView mCustomLv;
  // benutzerdefinierter Anpasser
  private CustomListViewAdapter mAdapter;
  // Inhaltsliste
  private List<String> contentList = new ArrayList<String>();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    initContentList();
    mCustomLv = (CustomListView) findViewById(R.id.custom_lv);
    mCustomLv.setOnDeleteListener(new OnDeleteListener() {
      @Override
      public void onDelete(int index) {
        contentList.remove(index);
        mAdapter.notifyDataSetChanged();
      }
    });
    mAdapter = new CustomListViewAdapter(this, 0, contentList);
    mCustomLv.setAdapter(mAdapter);
  }
  // Initialisiere Inhaltsliste
  private void initContentList() {
    for (int i = 0; i < 20; i++) {
      contentList.add("Inhaltsposition" + i);
    }
  }
  @Override
  public void onBackPressed() {
    if (mCustomLv.isDeleteShown()) {
      mCustomLv.hideDelete();
      return;
    }
    super.onBackPressed();
  }
}

7、Laufende Ergebnisse wie folgt:

Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die Anleitungstutorials mehr unterstützen.

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem jeweiligen Urheber. Der Inhalt wurde von Internetnutzern freiwillig bereitgestellt und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie Inhalte finden, die möglicherweise gegen das Urheberrecht verstoßen, freuen wir uns über eine E-Mail an: notice#w3Erklärung: Bitte ersetzen Sie im E-Mail-Text # durch @, um eine Beschwerde einzureichen und relevante Beweise bereitzustellen. Bei nachgewiesener Rechtsverletzung wird diese Seite sofort die beanstandeten Inhalte löschen.

Vermutlich gefällt Ihnen