Android 사용자 정의 View 알파벳 탐색 표시 줄 구현

많은 안 드 로 이 드 입문 프로그램 원숭이 들 에 게 안 드 로 이 드 사용자 정의 View 는 비교적 두 려 울 수 있 지만 이것 은 고수 가 진급 하 는 데 필수 적 인 길이 다.모든 준 비 는 사용자 정의 View 에 시간 을 들 여 글 을 많이 쓴다.
사고 분석:
1.사용자 정의 View 알파벳 탐색 표시 줄 구현
2,ListView 구현 연락처 목록
3.알파벳 네 비게 이 션 바 미끄럼 이벤트 처리
4.알파벳 네 비게 이 션 바 와 중간 자모의 연동
5.알파벳 네 비게 이 션 표시 줄 과 ListView 의 연동
효과 그림:

우선,우 리 는 먼저 메 인 레이아웃 파일 을 던 져 서 뒤의 코드 에 대한 설명 을 편리 하 게 합 니 다.

<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> 
 <edittext android:background="@drawable/search_border" android:drawableleft="@android:drawable/ic_menu_search" android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="8dp"> 
 <relativelayout android:layout_height="match_parent" android:layout_width="match_parent">
  <listview android:divider="@null" android:id="@+id/lv" android:layout_height="match_parent" android:layout_width="match_parent">
  <textview android:background="#888888" android:gravity="center" android:id="@+id/tv" android:layout_centerinparent="true" android:layout_height="50dp" android:layout_width="50dp" android:textcolor="#000000" android:textsize="18dp" android:visibility="gone">
  <com.handsome.tulin.view.navview android:id="@+id/nv" android:layout_alignparentright="true" android:layout_height="match_parent" android:layout_margin="16dp" android:layout_width="20dp">
 </com.handsome.tulin.view.navview></textview></listview></relativelayout>
</edittext></linearlayout>
단계 1:사용자 정의 알파벳 탐색 표시 줄 분석
사고 분석:
1.우 리 는 사용 할 때 폭 을 20dp 로 설정 하고 높이 는 부모 컨트롤 을 채 우 는 것 으로 설정 하기 때문에 여기 서 얻 은 폭 은 20dp 입 니 다.
2.순환 을 통 해 세로 로 된 자 모 를 그립 니 다.그림 을 그 릴 때마다 색 을 다시 설정 해 야 합 니 다.왜냐하면 우 리 는 선택 한 자모 색 이 기본 과 다 르 기 때 문 입 니 다.

public class NavView extends View {
 private Paint textPaint = new Paint();
 private String[] s = new String[]{
   "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 TextView tv;
 public NavView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 public NavView(Context context) {
  super(context);
 } 
 public NavView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
 } 
 private void initPaint() {
  textPaint.setTextSize(20);
  textPaint.setAntiAlias(true);
  textPaint.setColor(Color.BLACK);
 } 
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  //   
  drawText(canvas);
 }
 /**
  *    
  *
  * @param canvas
  */
 private void drawText(Canvas canvas) {
  //  View   
  int width = getWidth();
  int height = getHeight();
  //         
  int singleHeight = height / s.length;
  //   
  for (int i = 0; i < s.length; i++) {
   //      
   initPaint();
   //      
   if (choose == i) {
    textPaint.setColor(Color.RED);
   }
   //         
   float x = (width - textPaint.measureText(s[i])) / 2;
   float y = (i + 1) * singleHeight;
   canvas.drawText(s[i], x, y, textPaint);
   //    
   textPaint.reset();
  }
 }
}
STEP 2:ListView 연락처 목록 구현
사고 분석:
1.주 Activity 에서 하나의 데이터 배열 을 정의 하고 도구 류 를 사용 하여 배열 의 첫 번 째 자 모 를 가 져 옵 니 다.Collections 를 사용 하여 첫 번 째 자모 에 따라 정렬 합 니 다.도구 류 가 좀 길 기 때문에 붙 이지 않 습 니 다.
2.ListView 하위 레이아웃 을 만 들 고 Adapter 를 만들어 채 웁 니 다.
주 레이아웃:

public class MainActivity extends AppCompatActivity {
 private TextView tv;
 private ListView lv;
 private NavView nv;
 private List<user> list;
 private UserAdapter adapter;
 private String[] name = new String[]{
   "   ", "  ", "   ", "  ", "  ", "  ", "   ",
   "  ", "  ", "  ", "   ", "  ", "   ", "  ", "   ", "   ", "  ", "   ",
   "    ", "   ", "  ", "  ", "  ", "  ", "  ", "  ", "   ", "   ", "  ",
   "  ", "  ", "  ", "   ", "   ", "   ", "   ", "  ", "  ", "   "};
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView();
  initData();
 }
 private void initView() {
  tv = (TextView) findViewById(R.id.tv);
  lv = (ListView) findViewById(R.id.lv);
  nv = (NavView) findViewById(R.id.nv);
  nv.setTextView(tv);
 }
 private void initData() {
  //     
  list = new ArrayList<>();
  for (int i = 0; i < name.length; i++) {
   list.add(new User(name[i], CharacterUtils.getFirstSpell(name[i]).toUpperCase()));
  }
  //     
  Collections.sort(list, new Comparator<user>() {
   @Override
   public int compare(User lhs, User rhs) {
    return lhs.getFirstCharacter().compareTo(rhs.getFirstCharacter());
   }
  });
  //  ListView
  adapter = new UserAdapter(this, list);
  lv.setAdapter(adapter);
 }
}</user></user>
ListView 하위 레이아웃:

<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:background="#ffffff" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
  <textview android:background="#DBDBDA" android:id="@+id/tv_firstCharacter" android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="8dp" android:text="A" android:textcolor="#000000" android:textsize="14dp"> 
 <textview android:background="#ffffff" android:id="@+id/tv_name" android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="8dp" android:text="   " android:textcolor="#2196F3" android:textsize="14dp"> 
</textview></textview></linearlayout>
Adapter:

public class UserAdapter extends BaseAdapter {
 private List<user> list;
 private User user;
 private LayoutInflater mInflater;
 private Context context;
 public UserAdapter(Context context, List<user> list) {
  this.list = list;
  mInflater = LayoutInflater.from(context);
  this.context = context;
 }
 @Override
 public int getCount() {
  return list.size();
 }
 @Override
 public Object getItem(int position) {
  return list.get(position);
 }
 @Override
 public long getItemId(int position) {
  return position;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  if (convertView == null) {
   convertView = mInflater.inflate(R.layout.adapter_user, null);
  }
  ViewHolder holder = getViewHolder(convertView);
  user = list.get(position);
  if (position == 0) {
   //             
   holder.tv_firstCharacter.setVisibility(View.VISIBLE);
   holder.tv_firstCharacter.setText(user.getFirstCharacter());
   holder.tv_name.setText(user.getUsername());
  } else {
   //             ,    Ascii     
   if (CharacterUtils.getCnAscii(list.get(position - 1).getFirstCharacter().charAt(0)) <
     CharacterUtils.getCnAscii(user.getFirstCharacter().charAt(0))) {
    //              ,      
    holder.tv_firstCharacter.setVisibility(View.VISIBLE);
    holder.tv_firstCharacter.setText(user.getFirstCharacter());
    holder.tv_name.setText(user.getUsername());
   } else {
    //              ,     
    holder.tv_firstCharacter.setVisibility(View.GONE);
    holder.tv_name.setText(user.getUsername());
   }
  }
  return convertView;
 }
 /**
  *         
  *
  * @param view
  * @return
  */
 private ViewHolder getViewHolder(View view) {
  ViewHolder holder = (ViewHolder) view.getTag();
  if (holder == null) {
   holder = new ViewHolder(view);
   view.setTag(holder);
  }
  return holder;
 }
 /**
  *      
  */
 private class ViewHolder {
 
  private TextView tv_firstCharacter, tv_name;
 
  ViewHolder(View view) {
   tv_firstCharacter = (TextView) view.findViewById(R.id.tv_firstCharacter);
   tv_name = (TextView) view.findViewById(R.id.tv_name);
  }
 }
 
 /**
  *         
  *
  * @param s
  * @return
  */
 public int getSelectPosition(String s) {
  for (int i = 0; i < getCount(); i++) {
   String firChar = list.get(i).getFirstCharacter();
   if (firChar.equals(s)) {
    return i;
   }
  }
  return -1;
 }
}</user></user>
STEP 3:알파벳 네 비게 이 션 바 미끄럼 사건 처리,알파벳 네 비게 이 션 바 와 중간 자모의 연동
사고 분석:
1.사용자 정의 View 에 dispatchTouchEvent 를 다시 쓰 고 미끄럼 사건 을 처리 한 다음 에 true 로 돌아 갑 니 다.
2.주 Activity 에서 TextView 가 들 어 오 면 우리 가 미 끄 러 질 때 Text 를 설정 하고 풀 때 Text 를 사라 집 니 다.Text 를 설정 할 때 Text 의 위 치 를 계산 하고 너무 많이 미 끄 러 지면 배열 의 경 계 를 넘 는 문제 가 발생 하기 때문에 우 리 는 안에서 배열 의 경 계 를 넘 는 문 제 를 처리 합 니 다.
3.마지막 으로 인 터 페 이 스 를 제공 하여 우리 가 미 끄 러 진 자 모 를 기록 하고 뒤에서 ListView 와 연결 할 수 있 도록 합 니 다.

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
 //      
 int index = (int) (event.getY() / getHeight() * s.length);
 //      
 if (index >= s.length) {
  index = s.length - 1;
 } else if (index < 0) {
  index = 0;
 }
 switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(Color.GRAY);
   //      
   choose = index;
   //      
   tv.setVisibility(VISIBLE);
   tv.setText(s[choose]);
   //  ListView    
   if (listener != null) {
    listener.touchCharacterListener(s[choose]);
   }
   //  
   invalidate();
   break;
  default:
   setBackgroundColor(Color.TRANSPARENT);
   //        
   choose = -1;
   //      
   tv.setVisibility(GONE);
   //  
   invalidate();
   break;
 }
 return true;
}
public onTouchCharacterListener listener;
public interface onTouchCharacterListener {
 void touchCharacterListener(String s);
} 
public void setListener(onTouchCharacterListener listener) {
 this.listener = listener;
} 
/**
 *      TextView
 *
 * @param tv
 */
public void setTextView(TextView tv) {
 this.tv = tv;
}
STEP 4:알파벳 네 비게 이 션 표시 줄 과 ListView 의 연결
사고 분석:
1.우 리 는 이미 인 터 페 이 스 를 통 해 선택 한 자 모 를 전 달 했 고 adapter 에서 자모 에 따라 position 를 조회 하 는 방법 을 썼 습 니 다.이 럴 때 주 Activity 가 사용자 정의 View 설정 에 대한 감청 만 하면 판단 할 수 있 습 니 다.

//ListView    
nv.setListener(new NavView.onTouchCharacterListener() {
 @Override
 public void touchCharacterListener(String s) {
  int position = adapter.getSelectPosition(s);
  if (position != -1) {
   lv.setSelection(position);
  }
 }
});
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기