联系人列表
程序员文章站
2024-03-21 14:19:28
...
类似微信通讯录的联系人列表。
自定义View
public class MyTextView extends View {
private String[] words = {"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;
private int heightSize;
private int widSize;
private static final String TAG = "MyTextView";
private int mCurrentIndex = -1;
public MyTextView(Context context) {
this(context, null);
}
public MyTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initData();
}
private void initData() {
paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setTextSize(35);
paint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
widSize = MeasureSpec.getSize(widthMeasureSpec);
heightSize = MeasureSpec.getSize(heightMeasureSpec);
/**
* 直接继承View的自定义控件,padding默认是无法生效的,需要自己处理
*/
heightSize = heightSize - getPaddingBottom();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
for (int i=0; i<words.length; i++){
int left = widSize/2;
int height = heightSize/26 * i + heightSize/26;
if (i+1 == mCurrentIndex){
paint.setColor(Color.BLACK);
if (mOnSelectCharactorListener!=null){
mOnSelectCharactorListener.onSelectCharactor(words[i], mCurrentIndex);
}
}else {
paint.setColor(Color.RED);
}
/**
* 当你通过这个方法来获取尺寸的时候,你可以得到能够包裹文字的最小矩形
*/
paint.getTextBounds(words[i], 0, 1, rect);
canvas.drawText(words[i], left, height, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
float y = event.getY();
mCurrentIndex = getCurrentIndex(y);
if (mOnSelectCharactorListener!=null){
mOnSelectCharactorListener.onMotionEventAction(event);
}
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
mCurrentIndex = -1;
invalidate();
break;
}
return true;
}
private int getCurrentIndex(float y){
int currentIndex = (int) (y / (heightSize / 26) + 1);
if (currentIndex < 1){
currentIndex = 1;
}else if (currentIndex > 26){
currentIndex = 26;
}
return currentIndex;
}
private OnSelectCharactorListener mOnSelectCharactorListener;
public void setOnSelectCharactorListener(OnSelectCharactorListener onSelectCharactorListener){
mOnSelectCharactorListener = onSelectCharactorListener;
}
interface OnSelectCharactorListener{
void onSelectCharactor(String word, int currentIndex);
void onMotionEventAction(MotionEvent event);
}
}
上面代码中,是联系人列表中的拼音索引。
public class ConnectListAdapter extends BaseAdapter {
private static final String TAG = "ConnectListAdapter";
private SourceName mSourceName;
private Map<String, Integer> charPosition;
private ArrayList<Person> persons;
private Context context;
public ConnectListAdapter(SourceName sourceName, Context context){
this.mSourceName = sourceName;
persons = mSourceName.getPersons();
this.context = context;
charPosition = new HashMap<>();
}
@Override
public int getCount() {
return persons.size();
}
@Override
public Object getItem(int position) {
return persons.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null){
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_person, parent, false);
viewHolder.textViewChar = convertView.findViewById(R.id.tv_name_first_char);
viewHolder.textName = convertView.findViewById(R.id.tv_name);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
Person person = persons.get(position);
String currPinYinFirstChar = PinYinUtils.getPinYinFirstChar(person.getPinyin());
if (position > 0 && currPinYinFirstChar.equals(PinYinUtils.getPinYinFirstChar(persons.get(position - 1).getPinyin()))){
viewHolder.textViewChar.setVisibility(View.GONE);
}else {
charPosition.put(currPinYinFirstChar, position);
Log.d(TAG, "currPinYinFirstChar: "+currPinYinFirstChar);
Log.d(TAG, "charPosition.size: "+charPosition.size());
viewHolder.textViewChar.setVisibility(View.VISIBLE);
viewHolder.textViewChar.setText(currPinYinFirstChar);
}
viewHolder.textName.setText(person.getName());
return convertView;
}
public Map<String, Integer> getCharPosition(){
if (charPosition == null){
return null;
}
return charPosition;
}
static class ViewHolder{
TextView textViewChar;
TextView textName;
}
}
上面是listView的适配器。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int TIME_TO_GONE = 101;
private MyTextView characView;
private ViewStub stubView;
private TextView textView;
private ListView listView;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case TIME_TO_GONE:
stubView.setVisibility(View.GONE);
characView.setBackgroundColor(Color.GRAY);
characView.getBackground().setAlpha(0);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
characView = (MyTextView) findViewById(R.id.charactor);
listView = (ListView) findViewById(R.id.lv_name);
characView.setOnSelectCharactorListener(new ViewOnSelectCharactorListener());
//characView.setOnClickListener(new ViewOnClickListener());
initData();
}
private ConnectListAdapter connectListAdapter;
private Map<String, Integer> charPosition;
private ArrayList<Person> persons;
private void initData() {
connectListAdapter = new ConnectListAdapter(SourceName.getSourceName(), getApplicationContext());
listView.setAdapter(connectListAdapter);
persons = SourceName.getSourceName().getPersons();
}
class ViewOnSelectCharactorListener implements MyTextView.OnSelectCharactorListener{
@Override
public void onSelectCharactor(String word, int currentIndex) {
if (stubView==null){
stubView = (ViewStub) findViewById(R.id.stub_charactor_view);
stubView.inflate();
}
if (stubView.getVisibility() == View.GONE){
stubView.setVisibility(View.VISIBLE);
}
textView = (TextView) findViewById(R.id.charactor_text);
textView.setText(word);
characView.setBackgroundColor(Color.GRAY);
charPosition = connectListAdapter.getCharPosition();
if (charPosition != null){
if (charPosition.containsKey(word)){
if (charPosition.get(word) > -1){
listView.setSelection(charPosition.get(word));
}
}else {
for (int i=0; i<persons.size(); i++){
String pinYinFirstChar = PinYinUtils.getPinYinFirstChar(persons.get(i).getPinyin());
if (word.equals(pinYinFirstChar)){
listView.setSelection(i);
charPosition.put(word, i);
break;
}
charPosition.put(word, -1);
}
}
}
}
@Override
public void onMotionEventAction(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
handler.removeCallbacksAndMessages(null);
break;
case MotionEvent.ACTION_UP:
handler.sendEmptyMessage(TIME_TO_GONE);
break;
}
}
}
class ViewOnClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
}
}
}
上面也就是在MainActivity中的逻辑了。