SoFunction
Updated on 2025-04-10

Android development implements quick positioning of sidebars based on letters

Arrange the List by the first letter and quickly position the first letter, and has been widely used in Android development. Today I will also implement this control myself to encapsulate it, which is convenient for future use.Generally, it can be implemented in two steps:First, make your control inherit from the View and draw the graphically; then calculate the letters of the current touch based on the touch position, and implement the callback interface method.

Let’s practice:

1. Create your own control class and inherit from View.Notice:You cannot just declare a constructor containing a constructor parameter Context, so that our control cannot be called in the xml file, because the parameter passing between xml calling controls in Android is performed through the AttributeSet parameter in the constructor parameter. Without this parameter, our control cannot be used in the xml. Here I have added three constructors of the parent class View. Here I only need to call the constructor of the parent class, without additional operations.

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. Draw characters:The drawn part is implemented by replicating the onDraw method of the parent class and drawing it through Paint

1) First declare a member variable to save our character array and initialize a member variable of the 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 character, and then loop through the entire array to draw the characters

@Override
  protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  (canvas);
  int width = getWidth();
  int height = getHeight();
   int singleHeight = height / ;
  for (int i = 0; i < ; i++) {
   //Make relevant parameter settings for paint   (getResources().getColor());
   (Typeface.DEFAULT_BOLD);
   (true);
   (20);
   if (i == choose) {//The choice variable represents the character position currently touched, and if there is no touch, it is -1    (getResources().getColor());
    (true);
   }
   // Calculate the character drawing position   float xPos = width / 2 - (characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   //Draw characters on the canvas   (characters[i], xPos, yPos, paint);
   ();//Don't forget to remake Paint after each drawing is completed  }
 }

Notice:Don't forget to reset Paint after each drawing is finished

3. Handle touch events:Implementation by rewriting the dispatchTouchEvent method of the parent class

1) First we need to design a callback interface, and when the character we touch changes, we can execute the callback interface method

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

2) When a press event or a moving event occurs, we calculate the currently touched character based on the position of the touch point. If the character is different from the character we display, we execute the callback interface method and redraw the View; when a lift event occurs, we update the currently displayed character to -1, indicating that there are no characters currently displayed, and redraw the View.

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

Attached the overall source code:

package ;
 
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
 
import ;
 
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) {
   = onTouchLetterChangedListener;
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  (canvas);
  int width = getWidth();
  int height = getHeight();
  int singleHeight = height / ;
  for (int i = 0; i < ; i++) {
   // Make relevant parameter settings for paint   (getResources().getColor());
   (Typeface.DEFAULT_BOLD);
   (true);
   (20);
   if (i == choose) {// The choice variable represents the currently displayed character position, if there is no touch, it is -1    (getResources().getColor());
    (true);
   }
   // Calculate the character drawing position   float xPos = width / 2 - (characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   // Draw characters on canvas   (characters[i], xPos, yPos, paint);
   ();// Don't forget to remake Paint after each drawing is completed  }
 }
 
 
 @Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  int action = ();
  float y = ();
  int c = (int) (y / getHeight() * );
 
  switch (action) {
  case MotionEvent.ACTION_UP:
   choose = -1;//
   setBackgroundColor(0x0000);
   invalidate();
   break;
 
  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(getResources().getColor());
   if (choose != c) {
    if (c >= 0 && c < ) {
     if (mOnTouchLetterChangedListener != null) {
      mOnTouchLetterChangedListener
        .touchLetterChanged(characters[c]);
     }
     choose = c;
     invalidate();
    }
   }
   break;
  }
  return true;
 }
 
 public interface OnTouchLetterChangedListener {
  public void touchLetterChanged(String s);
 }
 
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.