这是Android学习过程中的第二篇笔记
ImageView的src和background的区别
1.src是内容,background是背景
2.当使用src是,不会拉伸,当使用background是图片会根据imageview的大小拉伸。
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/mine_attention_normal"
/>
<ImageView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="@drawable/mine_attention_normal"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/mine_attention_normal"
/>
<ImageView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:src="@drawable/mine_attention_normal"
/>
adjustViewBounds
adjustViewBounds需要配合maxWidth和maxHeight使用
<ImageView
android:id="@+id/iv2"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/star_bg"
android:maxWidth="80dp"
android:maxHeight="50dp"
android:adjustViewBounds="true"
/>
ScrollView
滑动到底部和顶部
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "MainActivity";
private ImageView iv;
private TextView tv;
private ScrollView scrollView;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTop = (Button) findViewById(R.id.top);
Button btnBottom = (Button) findViewById(R.id.bottom);
scrollView = (ScrollView) findViewById(R.id.scrollView);
linearLayout = (LinearLayout) findViewById(R.id.child);
btnTop.setOnClickListener(this);
btnBottom.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.top:
scrollView.fullScroll(ScrollView.FOCUS_UP);
break;
case R.id.bottom:
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
// smothScrollTo(scrollView,linearLayout);
break;
}
}
/**
* 瞬间滑动
* @param scrollView
* @param innerView
*/
public void smothScrollTo(final View scrollView, final View innerView){
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
//1854:2186
Log.d(TAG, "run: "+scrollView.getMeasuredHeight()+":"+innerView.getMeasuredHeight());
int offset = innerView.getMeasuredHeight() - scrollView.getMeasuredHeight();
if (offset < 0) {
offset = 0;
}
scrollView.scrollTo(0,offset);
}
});
}
}
ListView
addHearView和addFooterView要放在setAdapter之前
焦点问题
如果listview的条目中有button,checkbox等控件,默认情况下只有控件能响应点击事件,给listview设置条目点击无效,有两种解决办法:
1.设置控件focusable为false
/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮"
android:focusable="false"
/>
2.条目跟布局添加
android:descendantFocusability="blocksDescendants"
checkbox错乱
解决办法:
final Anim anim = animList.get(position);
holder.btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//给对象加一个属性,代表当前状态
anim.isChecked = isChecked;
Toast.makeText(getBaseContext(),anim.name,Toast.LENGTH_SHORT).show();
}
});
//因为每个条目对应的对象不一样,可以根据对象的状态判断是否选中checkbox
holder.btn.setChecked(anim.isChecked);
万能适配器
public abstract class CustomAdapter<T> extends BaseAdapter {
protected Context mContext;
protected List<T> mList;
public CustomAdapter(Context context,List<T> list){
mContext = context;
mList = list;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public T getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = ViewHolder.get(mContext, convertView, parent, R.layout.list_item_layout, position);
convert(holder,getItem(position));
return holder.getConvertView();
}
public abstract void convert(ViewHolder holder,T t);
}
public class ViewHolder {
private SparseArray<View> mViews;
private int mPosition;
private View mConvertView;
public ViewHolder(Context context, ViewGroup parent,int layoutId,int position){
mPosition = position;
mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId,parent,false);
mConvertView.setTag(this);
}
public static ViewHolder get(Context context,View convertView,ViewGroup parent,int layoutId,int position){
if(convertView == null) {
return new ViewHolder(context,parent,layoutId,position);
} else {
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.mPosition = position;
return viewHolder;
}
}
public <T extends View> T getView(int viewId){
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId,view);
}
return (T) view;
}
public View getConvertView(){
return mConvertView;
}
public ViewHolder setText(int viewId,CharSequence value) {
TextView textView = getView(viewId);
textView.setText(value);
return this;
}
public ViewHolder setImageResource(int viewId,int resourceId){
ImageView imageView = getView(viewId);
imageView.setImageResource(resourceId);
return this;
}
public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener){
getView(viewId).setOnClickListener(listener);
return this;
}
}
使用(带错乱解决)
public class AnimAdapter extends CustomAdapter<Anim> {
private List<Integer> mList = new ArrayList<>();
public AnimAdapter(Context context, List<Anim> list) {
super(context, list);
}
@Override
public void convert(final ViewHolder holder, final Anim anim) {
holder.setText(R.id.name,anim.name).setText(R.id.func,anim.speak);
final CheckBox cb = holder.getView(R.id.btn);
cb.setChecked(false);
if (mList.contains(holder.getPosition())) {
cb.setChecked(true);
}
// cb.setChecked(mList.contains(holder.getPosition()));
holder.setOnClickListener(R.id.name, new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,anim.name,Toast.LENGTH_SHORT).show();
}
});
holder.setOnClickListener(R.id.btn, new View.OnClickListener() {
@Override
public void onClick(View v) {
if(cb.isChecked()) {
mList.add(holder.getPosition());
} else {
mList.remove(holder.getPosition());
}
}
});
}
}
多点触控
public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
private static final String TAG = "MainActivity";
private ImageView imageview;
//缩放控制
private Matrix matrix = new Matrix();
private Matrix saveMatrix = new Matrix();
//不同状态表示
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
// 定义第一个按下的点,两只接触点的重点,以及出事的两指按下的距离:
private PointF startPoint = new PointF();
private PointF midPoint = new PointF();
private float oriDis = 1f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview = (ImageView) findViewById(R.id.imageview);
imageview.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView imageView = (ImageView) v;
switch (event.getAction()&MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
matrix.set(imageView.getImageMatrix());
saveMatrix.set(matrix);
startPoint.set(event.getX(),event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oriDis = distance(event);
if(oriDis>10f){
saveMatrix.set(matrix);
midPoint = middle(event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_MOVE:
if(mode==DRAG) {
matrix.set(saveMatrix);
Log.d(TAG, "onTouch: "+(event.getX() - startPoint.x));
matrix.postTranslate(event.getX() - startPoint.x,event.getY() - startPoint.y);
}else if(mode==ZOOM){
float newDist = distance(event);
if(newDist>10f){
matrix.set(saveMatrix);
float scale = newDist / oriDis;
matrix.postScale(scale, scale, midPoint.x, midPoint.y);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
mode = NONE;
break;
}
imageView.setImageMatrix(matrix);
return true;
}
private float distance(MotionEvent event){
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x*x+y*y);
}
private PointF middle(MotionEvent event){
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
return new PointF(x/2,y/2);
}
}
手势关闭和启动Activity
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private ViewConfiguration configuration;
private GestureDetector detector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyGesureListener listener = new MyGesureListener();
configuration = ViewConfiguration.get(this);
detector = new GestureDetector(this,listener);
Log.d(TAG, "onCreate: "+configuration.getScaledTouchSlop());
}
public class MyGesureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if(e1.getY() - e2.getY() > configuration.getScaledTouchSlop()) {
Toast.makeText(getBaseContext(),"上滑启动Activity",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getBaseContext(),SecondActivity.class);
startActivity(intent);
} else if (e2.getY() - e1.getY()>configuration.getScaledTouchSlop()) {
finish();
Toast.makeText(getBaseContext(),"下滑关闭Activity",Toast.LENGTH_SHORT).show();
}
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return detector.onTouchEvent(event);
}
}
使用getBaseContext出现的异常:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:682)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:316)