Android Development and Implementation of Quick Positioning Sidebar According to Letters

  • 2021-12-21 04:52:31
  • OfStack

According to the first letter of List arrangement, and according to the first letter of fast positioning in the development of Android has been a large number of applications, today I also personally to achieve 1, encapsulation of this control, but also convenient for future use. Generally speaking, this control can be implemented in two steps: first, make your control inherit from View and draw graphics; Then, according to the touch position, the current touch letter is calculated, and the callback interface method is realized.

Let's do it below:

1. Create your own control class and inherit from View. Note: You can't just declare a constructor with 1 construction parameter Context, so our control can't be called in xml file, because the parameter transfer between xml calling controls in Android is carried out through AttributeSet parameter in construction parameters, without which our control can't be used in xml. Here I added three constructors of the parent class View, which only need to call the constructor of the parent class, and no additional operation is needed.


public QuicLocationBar(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  // TODO Auto-generated constructor stub
 }
 
 public QuicLocationBar(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
 }
 
 public QuicLocationBar(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
 }

2. Drawing characters: The drawing part is realized by copying the onDraw method of the parent class, and drawn by Paint

1) First, declare a member variable to hold our character array, and initialize a member variable of Paint class to help us draw characters


private String characters[] = { "#", "A", "B", "C", "D", "E", "F", "G",
   "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
   "U", "V", "W", "X", "Y", "Z" };
 private Paint paint = new Paint();

2) Divide the total height by the length of the string array to get the height of each 1 character, and then loop through the entire array to draw the characters


@Override
  protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  int width = getWidth();
  int height = getHeight();
   int singleHeight = height / characters.length;
  for (int i = 0; i < characters.length; i++) {
   // Right paint Set related parameters 
   paint.setColor(getResources().getColor(R.color.myblack));
   paint.setTypeface(Typeface.DEFAULT_BOLD);
   paint.setAntiAlias(true);
   paint.setTextSize(20);
   if (i == choose) {//choose Variable represents the position of the character currently touched, or if there is no touch -1
    paint.setColor(getResources().getColor(R.color.myred));
    paint.setFakeBoldText(true);
   }
   // Calculate the drawing position of characters 
   float xPos = width / 2 - paint.measureText(characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   // Drawing Characters on Canvas 
   canvas.drawText(characters[i], xPos, yPos, paint);
   paint.reset();// Don't forget to reproduce after each drawing Paint
  }
 }

Note: Don't forget to reset Paint after each drawing

3. Handling touch events: By overriding the dispatchTouchEvent method of the parent class

1) First of all, we should design a callback interface, and when the characters we touch change, we can execute the method of the callback interface


public interface OnTouchLetterChangedListener {
  public void touchLetterChanged(String s);
 }

2) When a pressing event or a moving event occurs, we calculate the current touched character according to the position of the touch point, if it is different from the displayed character, we execute the method of callback interface, and carry out the redrawing of View; when a lifting event occurs, we update the currently displayed character to-1, indicating that no character is currently displayed, and carry out the redrawing of View.


@Override
  public boolean dispatchTouchEvent(MotionEvent event) {
  int action = event.getAction();
  float y = event.getY();
  int c = (int) (y / getHeight() * characters.length);
 
  switch (action) {
  case MotionEvent.ACTION_UP:
   choose = -1;//
   setBackgroundColor(0x0000);
   invalidate();
   break;
 
  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(getResources().getColor(R.color.darkgray));
   if (choose != c) {
    if (c >= 0 && c < characters.length) {
     if (mOnTouchLetterChangedListener != null) {
      mOnTouchLetterChangedListener
        .touchLetterChanged(characters[c]);
     }
     choose = c;
     invalidate();
    }
   }
   break;
  }
  return true;// Return true Indicates that touch events are not being distributed downward 
 }

Attached is the overall source code:


package com.example.test.widget;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
 
import com.example.gymapp.R;
 
public class QuicLocationBar extends View {
 
 private String characters[] = { "#", "A", "B", "C", "D", "E", "F", "G",
   "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
   "U", "V", "W", "X", "Y", "Z" };
 private int choose = -1;
 private Paint paint = new Paint();
 private OnTouchLetterChangedListener mOnTouchLetterChangedListener;
 
 public QuicLocationBar(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  // TODO Auto-generated constructor stub
 }
 
 public QuicLocationBar(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
 }
 
 public QuicLocationBar(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
 }
 
 public void setOnTouchLitterChangedListener(
   OnTouchLetterChangedListener onTouchLetterChangedListener) {
  this.mOnTouchLetterChangedListener = onTouchLetterChangedListener;
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  int width = getWidth();
  int height = getHeight();
  int singleHeight = height / characters.length;
  for (int i = 0; i < characters.length; i++) {
   //  Right paint Set related parameters 
   paint.setColor(getResources().getColor(R.color.myblack));
   paint.setTypeface(Typeface.DEFAULT_BOLD);
   paint.setAntiAlias(true);
   paint.setTextSize(20);
   if (i == choose) {// choose Variable represents the currently displayed character position, or if there is no touch -1
    paint.setColor(getResources().getColor(R.color.myred));
    paint.setFakeBoldText(true);
   }
   //  Calculate the drawing position of characters 
   float xPos = width / 2 - paint.measureText(characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   //  Drawing Characters on Canvas 
   canvas.drawText(characters[i], xPos, yPos, paint);
   paint.reset();//  Don't forget to reproduce after each drawing Paint
  }
 }
 
 
 @Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  int action = event.getAction();
  float y = event.getY();
  int c = (int) (y / getHeight() * characters.length);
 
  switch (action) {
  case MotionEvent.ACTION_UP:
   choose = -1;//
   setBackgroundColor(0x0000);
   invalidate();
   break;
 
  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(getResources().getColor(R.color.darkgray));
   if (choose != c) {
    if (c >= 0 && c < characters.length) {
     if (mOnTouchLetterChangedListener != null) {
      mOnTouchLetterChangedListener
        .touchLetterChanged(characters[c]);
     }
     choose = c;
     invalidate();
    }
   }
   break;
  }
  return true;
 }
 
 public interface OnTouchLetterChangedListener {
  public void touchLetterChanged(String s);
 }
 
}

Related articles: