Android仿微信通讯录滑动快速定位功能

作者:袖梨 2022-06-25

先给大家展示下效果图:

实现代码如下:

下面简单说下实现原理。

 

 代码如下复制代码

publicclassIndexBarextendsLinearLayoutimplementsView.OnTouchListener {

  privatestaticfinalString[] INDEXES =newString[]{"#","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"};

  privatestaticfinalintTOUCHED_BACKGROUND_COLOR =0x40000000;

  privateOnIndexChangedListener mListener;

  publicvoidsetOnIndexChangedListener(OnIndexChangedListener listener) {

    mListener = listener;

  }

  publicIndexBar(Context context) {

    this(context,null);

  }

  publicIndexBar(Context context, AttributeSet attrs) {

    this(context, attrs,0);

  }

  publicIndexBar(Context context, AttributeSet attrs,intdefStyleAttr) {

    super(context, attrs, defStyleAttr);

    init(attrs);

  }

  privatevoidinit(AttributeSet attrs) {

    TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.IndexBar);

    floatindexTextSize = ta.getDimension(R.styleable.IndexBar_indexTextSize, Utils.sp2px(getContext(),12));

    intindexTextColor = ta.getColor(R.styleable.IndexBar_indexTextColor,0xFF616161);

    ta.recycle();

    setOrientation(VERTICAL);

    setOnTouchListener(this);

    for(String index : INDEXES) {

      TextView text =newTextView(getContext());

      text.setText(index);

      text.setTextSize(TypedValue.COMPLEX_UNIT_PX, indexTextSize);

      text.setTextColor(indexTextColor);

      text.setGravity(Gravity.CENTER);

      LinearLayout.LayoutParams params =newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,0,1);

      text.setLayoutParams(params);

      addView(text);

    }

  }

  @Override

  publicbooleanonTouch(View v, MotionEvent event) {

    switch(event.getAction()) {

      caseMotionEvent.ACTION_DOWN:

        setBackgroundColor(TOUCHED_BACKGROUND_COLOR);

        handle(v, event);

        returntrue;

      caseMotionEvent.ACTION_MOVE:

        handle(v, event);

        returntrue;

      caseMotionEvent.ACTION_UP:

        setBackgroundColor(Color.TRANSPARENT);

        handle(v, event);

        returntrue;

    }

    returnsuper.onTouchEvent(event);

  }

  privatevoidhandle(View v, MotionEvent event) {

    inty = (int) event.getY();

    intheight = v.getHeight();

    intposition = INDEXES.length * y / height;

    if(position<0) {

      position =0;

    }elseif(position >= INDEXES.length) {

      position = INDEXES.length -1;

    }

    String index = INDEXES[position];

    booleanshowIndicator = event.getAction() != MotionEvent.ACTION_UP;

    if(mListener !=null) {

      mListener.onIndexChanged(index, showIndicator);

    }

  }

  publicinterfaceOnIndexChangedListener {

    voidonIndexChanged(String index,booleanshowIndicator);

  }

}

 

使用

 

 代码如下复制代码

publicclassCompanyActivityextendsBaseActivityimplementsIndexBar.OnIndexChangedListener {

  @Bind(R.id.lv_company)

  ListView lvCompany;

  @Bind(R.id.ib_indicator)

  IndexBar ibIndicator;

  @Bind(R.id.tv_indicator)

  TextView tvIndicator;

  privateListmCompanyList =newArrayList<>();

  @Override

  protectedvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_company);

    // ...

  }

  @Override

  publicvoidonIndexChanged(String index,booleanshowIndicator) {

    intposition = -1;

    for(CompanyEntity company : mCompanyList) {

      if(TextUtils.equals(company.getName(), index)) {

        position = mCompanyList.indexOf(company);

        break;

      }

    }

    if(position != -1) {

      lvCompany.setSelection(position);

    }

    tvIndicator.setText(index);

    tvIndicator.setVisibility(showIndicator ? View.VISIBLE : View.GONE);

  }

}

 

继承自LinearLayout,添加了26个字母索引TextView,当手指滑动时通知Activity更新界面。

核心是OnTouchListener,手指滑动的时候根据当前Y坐标计算出手指所在的索引位置,要注意临界值。

相关文章

精彩推荐