Android学习笔记(二)

本文详细解析了Android开发中的ImageView使用技巧,包括src与background的区别、调整视图边界的方法;探讨了ScrollView的滚动控制及ListView的常见问题解决策略;并深入介绍了多点触控处理与手势识别的技术实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值