android原生,Contact 应用
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.Locale;
public class BladeView extends View {
private int mMinCharHeight = 1;
private int mMaxCharHeight = 60;
private int mCharClickHeight = 5;
private int mCharHeight = 5;
private OnItemClickListener mOnItemClickListener;
private PopupWindow mPopupWindow;
private TextView mPopupText;
private int mTextColor;
private boolean mTouched = false;
private int mCurItem = 0;
private float mHeight = 0;
private static int BLADE_BACKGROUND_WIDTH = 25;
private int[] mTextColorSet;
private final String[] mAlphabet = {
"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 String TAG = "BladeView";
private Context mContext;
public BladeView(Context context) {
super(context);
initView(context);
}
public BladeView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public BladeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
private void initView(Context context){
mContext = context;
BLADE_BACKGROUND_WIDTH = mContext.getResources().getDimensionPixelSize(
R.dimen.contact_bladeview_width);//72dp
mTextColorSet = new int[mAlphabet.length];
mTextColor = Color.GRAY;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
mHeight = (float) heightSize;
int charNumber = mAlphabet.length;
int charHeigtht = heightSize / charNumber;
if (charHeigtht < mMinCharHeight) {
heightSize = mMinCharHeight * charNumber;
mCharHeight = mMinCharHeight;
mCharClickHeight = mCharHeight;
} else if (charHeigtht <= mMaxCharHeight) {
mCharHeight = charHeigtht;
mCharClickHeight = mCharHeight;
} else {
mCharHeight = mMaxCharHeight;
mCharClickHeight = charHeigtht;
}
setMeasuredDimension(BLADE_BACKGROUND_WIDTH, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(mTextColor);
paint.setAntiAlias(true);
paint.setTextSize(mCharHeight - 6);
paint.setColor(this.getResources().getColor(R.color.contact_bladeview_index_text_color));//#B2B2B2
int charNumber = mAlphabet.length;
for (int i = 0; i < charNumber; ++i) {
String currentChar = mAlphabet[i];
if (mTextColorSet[i] == Color.TRANSPARENT) {
if (mTouched) {
paint.setColor(this.getResources().getColor(
R.color.contact_bladeview_index_pressed_text_color));//#FFFFFFFF
} else {
paint.setColor(this.getResources().getColor(
R.color.contact_bladeview_index_text_color));//#B2B2B2
}
}
float y = (i + 1) * mCharHeight;
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (i % 3 != 0) {
currentChar = " ";
}
paint.setTextSize((mCharHeight) * 2);
y = (i + 2) * mCharHeight;
canvas.drawText(
currentChar,
((float) BLADE_BACKGROUND_WIDTH - (float) paint
.measureText(currentChar)) / (float) 2, y,
paint);
} else {
paint.setTextSize(mCharHeight);
y = (i + 1) * (mHeight / (float) mAlphabet.length);
canvas.drawText(
currentChar,
((float) BLADE_BACKGROUND_WIDTH - (float) paint
.measureText(currentChar)) / (float) 2, y,
paint);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
final int charNumber = mAlphabet.length;
if (action == MotionEvent.ACTION_DOWN
|| action == MotionEvent.ACTION_MOVE) {
getParent().requestDisallowInterceptTouchEvent(true);
int item = (int) (event.getY() / mCharClickHeight);
if (item < 0 || item >= charNumber) {
return true;
}
showPopup(item);
performItemClicked(item);
mTouched = true;
mCurItem = item;
} else {
dismissPopup();
mTouched = false;
}
return true;
}
private void showPopup(int item) {
if (mPopupWindow == null) {
mPopupWindow = new PopupWindow(this.getResources()
.getDimensionPixelSize(
R.dimen.contact_bladeview_popup_width/*80sp*/), this
.getResources().getDimensionPixelSize(
R.dimen.contact_bladeview_popup_width/*80sp*/));
mPopupText = new TextView(getContext());
mPopupText.setTextSize(this.getResources().getDimension(
R.dimen.contact_bladeview_popup_text_size));
if (isRTL()) {
mPopupText
.setBackgroundResource(R.drawable.letter_back_left);
} else {
mPopupText
.setBackgroundResource(R.drawable.letter_back_right);
}
mPopupText.setTextColor(this.getResources().getColor(
R.color.contact_bladeview_popup_text_color));//#FFFFFF
mPopupText.setGravity(Gravity.CENTER_HORIZONTAL
| Gravity.CENTER_VERTICAL);
mPopupWindow.setContentView(mPopupText);
}
String text = mAlphabet[item];
mPopupText.setText(text);
if (!mPopupWindow.isShowing()) {
if (isRTL()) {
mPopupWindow.showAtLocation(getRootView(), Gravity.CENTER_HORIZONTAL
| Gravity.LEFT, BLADE_BACKGROUND_WIDTH, 20);
} else {
mPopupWindow.showAtLocation(getRootView(), Gravity.CENTER_HORIZONTAL
| Gravity.RIGHT, BLADE_BACKGROUND_WIDTH, 20);
}
}
}
private void dismissPopup() {
if (mPopupWindow != null) {
mPopupWindow.dismiss();
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
private void performItemClicked(int item) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(item);
}
}
public interface OnItemClickListener {
void onItemClick(int item);
}
private boolean isRTL() {
final Locale locale = Locale.getDefault();
return TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL;
}
}