我们在开发过程中兰冕会有选着城市地点等东西,这些都是常用的东西,所以我也就将他封装起来了先来看看效果吧
1.首先看下项目的结构:
2.看下整体的项目效果
三:主ativity
private Context context = LetterSortActivity.this;
private ClearEditText mClearEditText;
private TextView tv_mid_letter;
private ListView listView;
private MyLetterSortView right_letter;
private ItemBeanAdapter mAdapter;
private List<City> mlist = new ArrayList<City>();
private InputMethodManager inputMethodManager;
private View mCityContainer;
private FrameLayout mSearchContainer;
private ListView mSearchListView;
private SearchCityAdapter mSearchCityAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
setLinstener();
initData();
fillData();
}
protected void initData() {
getDataCity();
mAdapter = new ItemBeanAdapter(this, mlist);
listView.setEmptyView(findViewById(R.id.citys_list_load));
listView.setAdapter(mAdapter);
}
protected void initView() {
inputMethodManager = (InputMethodManager) this
.getSystemService(Context.INPUT_METHOD_SERVICE);
listView = (ListView) findViewById(R.id.list);
mClearEditText = (ClearEditText) findViewById(R.id.et_msg_search);
// 这里设置中间字母
right_letter = (MyLetterSortView) findViewById(R.id.right_letter);
tv_mid_letter = (TextView) findViewById(R.id.tv_mid_letter);
right_letter.setTextView(tv_mid_letter);
//搜索
mCityContainer = findViewById(R.id.city_content_container);
mSearchContainer = (FrameLayout) this.findViewById(R.id.search_content_container);
mSearchListView = (ListView) findViewById(R.id.search_list);
mSearchListView.setEmptyView(findViewById(R.id.search_empty));
mSearchContainer.setVisibility(View.GONE);
}
protected void setLinstener() {
// tv_reget_pwd.setOnClickListener(this);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
T.showShort(getApplicationContext(),
((City) mAdapter.getItem(position)).toString());
}
});
listView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 隐藏软键盘
if (getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
if (getCurrentFocus() != null)
inputMethodManager.hideSoftInputFromWindow(
getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
return false;
}
});
// 设置右侧触摸监听
right_letter
.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {
@Override
public void onTouchingLetterChanged(String s) {
// 该字母首次出现的位置
int position = mAdapter.getPositionForSection(s
.charAt(0));
if (position != -1) {
listView.setSelection(position);
}
}
});
// 根据输入框输入值的改变来过滤搜索
mClearEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// 当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
filterData2(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
mSearchListView
.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
// L.i(mSearchCityAdapter.getItem(position).toString());
T.showLong(getApplicationContext(), mSearchCityAdapter
.getItem(position).toString());
}
});
}
protected void fillData() {
// TODO Auto-generated method stub
}
private void getDataCity() {
new Thread(new Runnable() {
@Override
public void run() {
MyCityDBHelper myCityDBHelper = new MyCityDBHelper(context);
mlist = myCityDBHelper.getCityDB().getAllCity();
mHandler.sendEmptyMessage(0);
}
}).start();
// 对list进行排序
// Collections.sort(mlist, new PinyinComparator() {
// });
}
private void filterData2(String filterStr) {
mSearchCityAdapter = new SearchCityAdapter(LetterSortActivity.this,
mlist);
mSearchListView.setAdapter(mSearchCityAdapter);
mSearchListView.setTextFilterEnabled(true);
if (mlist.size() < 1 || TextUtils.isEmpty(filterStr)) {
mCityContainer.setVisibility(View.VISIBLE);
mSearchContainer.setVisibility(View.INVISIBLE);
} else {
mCityContainer.setVisibility(View.INVISIBLE);
mSearchContainer.setVisibility(View.VISIBLE);
mSearchCityAdapter.getFilter().filter(filterStr);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//
default:
break;
}
}
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
mAdapter.updateListView(mlist);
break;
default:
break;
}
}
};
四:编辑框view
public class ClearEditText extends EditText implements
OnFocusChangeListener, TextWatcher {
/**
* 删除按钮的引用
*/
private Drawable mClearDrawable;
public ClearEditText(Context context) {
this(context, null);
}
public ClearEditText(Context context, AttributeSet attrs) {
//这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle);
}
public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
mClearDrawable = getCompoundDrawables()[2];
if (mClearDrawable == null) {
mClearDrawable = getResources().getDrawable(R.drawable.search_clear);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);
setOnFocusChangeListener(this);
addTextChangedListener(this);
}
/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean touchable = event.getX() > (getWidth()
- getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) {
this.setText("");
}
}
}
return super.onTouchEvent(event);
}
/**
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
}
/**
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
* @param visible
*/
protected void setClearIconVisible(boolean visible) {
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
/**
* 当输入框里面内容发生变化的时候回调的方法
*/
@Override
public void onTextChanged(CharSequence s, int start, int count,
int after) {
setClearIconVisible(s.length() > 0);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
/**
* 设置晃动动画
*/
public void setShakeAnimation(){
this.setAnimation(shakeAnimation(5));
}
/**
* 晃动动画
* @param counts 1秒钟晃动多少下
* @return
*/
public static Animation shakeAnimation(int counts){
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(1000);
return translateAnimation;
}
五:MyLetterSortView 字母
public class MyLetterSortView extends View {
// 触摸事件
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
// 26个字母
public static String[] b = { "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 TextView mTextDialog;
public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}
public MyLetterSortView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyLetterSortView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLetterSortView(Context context) {
super(context);
}
/**
* 重写这个方法
*/
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获取焦点改变背景颜色.
int height = getHeight();// 获取对应高度
int width = getWidth(); // 获取对应宽度
int singleHeight = height / b.length;// 获取每一个字母的高度
for (int i = 0; i < b.length; i++) {
paint.setColor(Color.parseColor("#9da0a4"));
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
// paint.setTextSize(PixelUtil.sp2px(12));
paint.setTextSize(25);
// 选中的状态
if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
// x坐标等于中间-字符串宽度的一半.
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}
}
@SuppressWarnings("deprecation")
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();// 点击y坐标
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
switch (action) {
case MotionEvent.ACTION_UP:
setBackgroundDrawable(new ColorDrawable(0x00000000));
choose = -1;//
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.INVISIBLE);
}
break;
default:
//设置右侧字母列表[A,B,C,D,E....]的背景颜色
setBackgroundResource(R.drawable.letter_sort_background);
if (oldChoose != c) {
if (c >= 0 && c < b.length) {
if (listener != null) {
listener.onTouchingLetterChanged(b[c]);
}
if (mTextDialog != null) {
mTextDialog.setText(b[c]);
mTextDialog.setVisibility(View.VISIBLE);
}
choose = c;
invalidate();
}
}
break;
}
return true;
}
/**
* 向外公开的方法
*
* @param onTouchingLetterChangedListener
*/
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
还有一部分代码比较多,就不一一贴上了.