这是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)