Day_2021_3_2_DeakTest

本文介绍了一个自定义的 Android 图片视图组件 MyMatrix,通过该组件可以实现图片的位移、放大缩小、旋转及切变等矩阵变换效果。文章提供了完整的代码实现,并展示了如何通过按钮触发不同的变换效果。

matrix自定义类

package com.example.day_3_2_juzhentupian;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class MyMatrix extends View {
    Matrix matrix;
    Paint paint;
    Bitmap bitmap;
    public MyMatrix(Context context) {
        super(context);
        init();
    }

    public MyMatrix(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init(){
        matrix=new Matrix();
        paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap,matrix,paint);
    }
    public void tran(){
        matrix.reset();
        matrix.setTranslate(400,400);
        invalidate();
    }
    public void suofang(){
        matrix.reset();
        matrix.setScale(10, 10);
        invalidate();
    }
    public  void xuanzhuan(){
        matrix.reset();
        matrix.setRotate(40);
        invalidate();
    }
    public void skew() {
        matrix.reset();
        matrix.setSkew(10, 10);
        invalidate();
    }
}

main1页面

package com.example.day_3_2_juzhentupian;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private MyMatrix img;
    private Button translate;
    private Button scale;
    private Button rotate;
    private Button skew;
    private Button tiaozhuan;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        translate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                img.tran();
            }
        });
        scale.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                img.suofang();
            }
        });
        rotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                img.xuanzhuan();
            }
        });
        skew.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                img.skew();
            }
        });
        tiaozhuan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,Main2Activity.class);
                startActivity(intent);
            }
        });
    }

    private void initView() {
        img = (MyMatrix) findViewById(R.id.img);
        translate = (Button) findViewById(R.id.translate);
        scale = (Button) findViewById(R.id.scale);
        rotate = (Button) findViewById(R.id.rotate);
        skew = (Button) findViewById(R.id.skew);
        tiaozhuan = (Button) findViewById(R.id.tiaozhuan);
    }
}

main2页面

package com.example.day_3_2_juzhentupian;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
import com.bigkoo.pickerview.builder.TimePickerBuilder;
import com.bigkoo.pickerview.listener.OnOptionsSelectChangeListener;
import com.bigkoo.pickerview.listener.OnOptionsSelectListener;
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
import com.bigkoo.pickerview.view.OptionsPickerView;
import com.bigkoo.pickerview.view.TimePickerView;
import com.contrarywind.view.WheelView;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Main2Activity extends AppCompatActivity {

    private WheelView wheelView;
    private Button shijian;
    private Button sanji;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
        shijian.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showTimePickerView();
            }
        });
        sanji.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                initOptionPicker();
            }
        });
    }

    private void initView() {
        wheelView = (WheelView) findViewById(R.id.wheel_view);
        shijian = (Button) findViewById(R.id.shijian);
        sanji = (Button) findViewById(R.id.sanji);
    }

    private void showTimePickerView() {
        TimePickerView pvTime = new TimePickerBuilder(Main2Activity.this, new OnTimeSelectListener() {
            @Override
            public void onTimeSelect(Date date, View v) {
                Toast.makeText(Main2Activity.this, date.toString(), Toast.LENGTH_SHORT).show();
            }
        }).build();
        pvTime.show();//显示时间选择器
    }
    private void initOptionPicker() {
        final List<String> options1Items = new ArrayList<>();
        options1Items.add("河南省");
        options1Items.add("河北省");
        options1Items.add("北京市");

        List<String> options2Items_01 = new ArrayList<>();
        options2Items_01.add("洛阳市");
        options2Items_01.add("郑州市");
        options2Items_01.add("新乡");
        options2Items_01.add("平顶山");
        List<String> options2Items_02 = new ArrayList<>();
        options2Items_02.add("唐山");
        options2Items_02.add("廊坊");
        options2Items_02.add("沧州");
        List<String> options2Items_03 = new ArrayList<>();
        options2Items_03.add("海淀区");
        options2Items_03.add("房山区");
        options2Items_03.add("密云区");
        options2Items_03.add("朝阳区");

        final List<List<String>> options2Items = new ArrayList<>();
        options2Items.add(options2Items_01);
        options2Items.add(options2Items_02);
        options2Items.add(options2Items_03);


        OptionsPickerView optionsPickerView = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int options2, int options3, View v) {
                String tx = options1Items.get(options1)
                        + options2Items.get(options1).get(options2);
                Toast.makeText(getBaseContext(), tx, Toast.LENGTH_SHORT).show();
            }
        })
                .setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
                    @Override
                    public void onOptionsSelectChanged(int options1, int options2, int options3) {
                        String str = "options1: " + options1 + "\noptions2: " + options2 + "\noptions3: " + options3;
                        Toast.makeText(Main2Activity.this, str, Toast.LENGTH_SHORT).show();
                    }
                })
                .build();

        optionsPickerView.setPicker(options1Items, options2Items);
        optionsPickerView.show();
    }
}

相关布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".Main2Activity">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/shijian"
        android:text="时间"
        />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/sanji"
        android:text="三级联动"
        />
    <com.contrarywind.view.WheelView
        android:id="@+id/wheel_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.day_3_1_juzhentupian.MyMatrix
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/img"
        >

    </com.example.day_3_1_juzhentupian.MyMatrix>

    <LinearLayout
        android:layout_gravity="bottom"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="wrap_content">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="translate"
            android:layout_weight="1.0"
            android:id="@+id/translate" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="scale"
            android:layout_weight="1.0"
            android:id="@+id/scale" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="rotate"
            android:layout_weight="1.0"
            android:id="@+id/rotate" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="skew"
            android:layout_weight="1.0"
            android:id="@+id/skew" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="To Sec"
            android:layout_weight="1.0"
            android:id="@+id/tiaozhuan"
            />
    </LinearLayout>
</FrameLayout>

效果图片

在这里插入图片描述

在这里插入图片描述

效果分别为位移 放大 旋转 切分

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

作者jaaksi,源码pickerview,一个非常好用的 Android PickerView 库,内部提供 3 种常用类型的 Picker,支持扩展自定义 Picker:TimePicker:时间选择器,支持聚合模式的时间选择器(合并 v1.x 的 MixedTimePicker)OptionPicker:联动选择器效果图  APKDemo App下载连接PickerView READMEPicker通过组装 PickerView 实现常用的 Picker 选择器。上面已经列举提供的 3 中常用的 Picker。BasePickerPicker 基类:封装了 TopBar,PickerView 容器,create and add PickerView 方法,Picker 弹窗等方法。 三种 Picker 都继承自 BasePicker,你也可以继承它扩展自己的 Picker。APIapidescriptionsetPickerBackgroundColor设置 picker 背景setPadding设置 PickerView 父容器 padding 单位:pxsetTag给 Picker 设置 tag,用于区分不同的 picker 等。用法同 View setTaggetRootLayout获取 PickerView 的父容器,创建 DefaultTopBar 时必须指定setOnPickerChooseListener设置 picker 取消,确定按钮监听。可用于拦截选中操作setTopBar设置自定义 TopBarsetInterceptor设置拦截器createPickerView创建 PickerViewgetPickerViews获取 Picker 中所有的 pickerview 集合addPicker将创建的 PickerView 添加到上面集合中,createPickerView 内部已调用该方法findPickerViewByTag通过 tag 找到对应的 PickerViewisScrolling是否滚动未停止。滚动未停止的时候,不响应 Picker 的取消,确定按键getPickerDialog获取 Picker 弹窗。可以在 new 之后设置 dialog 属性show显示 picker 弹窗对比 github 上最受欢迎的同类库 Android-PickerView ,本库将 TopBar 等通用相关逻辑封装在基类中,并提供代码中创建 PickerView 方法,不需要再依赖 xml。用户自定义 Picker 时,继承 BasePicker,只需要处理自己的逻辑即可,简单便捷。 而对 Android-PickerView 来说,实现自定义 Picker,依然需要处理 TopBar 等逻辑,造成大量重复代码。TopBarTopBar:TopBar 通过抽象接口 ITopBar 来管理,实现 Picker 与 TopBar 的解耦。提供默认实现 DefaultTopBar。可实现接口定制自己的 TopBar。   public interface ITopBar {      /**       * @return topbar view       */      View getTopBarView();      /**       * @return 取消按钮 view       */      View getBtnCancel();      /**       * @return 确定按钮 view       */      View getBtnConfirm();      /**       * @return title view       */      TextView getTitleView();    }DefaultTopBar APIapidescriptionsetDividerColor设置 topbar bottom line colorsetDividerHeight设置 bottom divider line heightgetDivider获取 TopBar bottom linegetTitleView获取 TopBar title viewInterceptor拦截器:用于在 pickerview 创建时拦截,设置 pickerview 的属性。Picker 内部并不提供对 PickerView 的设置方法,而是通过 Interceptor 实现。这种设计用来实现 Picker 和 PickerView 的属性设置完美解耦。   private void init(){     mTimePicker.setInterceptor(new 
<think> 根据用户的查询,用户想了解DAY_OF_MONTH在编程中的含义及使用。结合提供的引用内容,我们可以进行以下分析: 1. 引用[2]中明确指出:DAY_OF_MONTH的主要作用是`cal.get(DAY_OF_MONTH)`,用来获得这一天在是这个月的第多少天。例如,如果是5月15日,那么DAY_OF_MONTH的值就是15。 2. 引用[2]还提到,Calendar设置DAY_OF_MONTH和DAY_OF_YEAR的目的不是用来+1(即增加日期),而是用于获取或设置日期的特定部分。增加日期应该使用`Calendar.DATE`。 3. 引用[3]展示了一个C语言函数`day_of_year`,它计算给定日期是该年的第几天。虽然不直接使用DAY_OF_MONTH常量,但展示了如何通过累加月份的天数来计算一年中的天数,这间接说明了在日期处理中,月份中的天数是一个基础概念。 4. 引用[1]提到了DAY_OF_WEEK_IN_MONTH,这与DAY_OF_MONTH不同,它计算的是当前星期在当前月中的出现次数(如第几个星期三)。 因此,我们可以总结如下: **DAY_OF_MONTH的含义**: 在编程中(特别是在Java的`Calendar`类中),`DAY_OF_MONTH`是一个字段常量,表示一个月中的第几天,取值范围通常是1到31(取决于月份)。例如,5月15日的`DAY_OF_MONTH`值为15。 **使用场景**: 1. **获取当前日期是一个月中的第几天**:使用`calendar.get(Calendar.DAY_OF_MONTH)`。 2. **设置日期为一个月的特定某一天**:使用`calendar.set(Calendar.DAY_OF_MONTH, day)`,其中`day`是想要设置的日期(1到31之间的整数)。 **示例代码(Java)**: ```java import java.util.Calendar; public class DayOfMonthExample { public static void main(String[] args) { // 获取当前日期 Calendar calendar = Calendar.getInstance(); // 获取今天是本月的第几天 int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); System.out.println("今天是本月的第 " + dayOfMonth + " 天"); // 设置日期为本月的第15天 calendar.set(Calendar.DAY_OF_MONTH, 15); System.out.println("设置后的日期: " + calendar.getTime()); } } ``` **注意事项**: - 在设置`DAY_OF_MONTH`时,如果指定的值超出了当前月份的有效天数(例如在4月设置31日),`Calendar`会自动调整日期(如将日期调整为下个月的1日)。这是由`Calendar`的宽松规则(lenient)决定的,默认是宽松模式。 - 与`DAY_OF_MONTH`类似,`Calendar`类还提供了其他日期字段,如`DAY_OF_WEEK`(一周中的第几天)、`DAY_OF_YEAR`(一年中的第几天)等。 **与DAY_OF_WEEK_IN_MONTH的区别**: 引用[1]提到,`DAY_OF_WEEK_IN_MONTH`表示当前星期在当前月中的出现次数(例如,5月1日是星期三,那么它是该月的第一个星期三;5月8日(下一个星期三)是第二个星期三)。而`DAY_OF_MONTH`就是简单的日期数字(1到31)。 综上所述,`DAY_OF_MONTH`是一个用于表示月内日期的基本字段,在日期操作中非常常用。 §§相关问题§§ 1. 如何获取当前日期是一周中的第几天(星期几)? 2. 在Java中如何安全地设置日期以避免超出月份范围? 3. `Calendar`类中的`DAY_OF_YEAR`字段有什么作用? 4. 如何处理不同月份的天数差异(如闰年二月)? </think>### DAY_OF_MONTH在编程中的含义及使用 **DAY_OF_MONTH**是编程中日期处理的核心概念,表示**一个月中的第几天**(即日期数值)。在不同编程语言中,其具体实现方式有所差异: #### 1. 核心含义 - **数值范围**:1 到 31(根据月份和闰年调整) - **作用**:标识给定日期在当月中的序数位置 例如:2023-05-15 的 DAY_OF_MONTH = 15 #### 2. 使用场景(以Java为例) ```java Calendar cal = Calendar.getInstance(); // 获取当日是该月第几天 int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); // 设置日期为该月第10天 cal.set(Calendar.DAY_OF_MONTH, 10); ``` > 关键区别:与`DAY_OF_YEAR`(年中第几天)不同,DAY_OF_MONTH仅关注当月内的日期序数[^2]。 #### 3. 底层实现原理 日期计算通常通过查表法实现(如引用[3]的C语言示例): ```c int tab[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31}, // 非闰年 {0,31,29,31,30,31,30,31,31,30,31,30,31} // 闰年 }; ``` 计算逻辑伪代码: $$ \text{DAY\_OF\_MONTH} = \text{day} + \sum_{i=1}^{\text{month}-1} \text{tab[leap][i]} $$ 其中`leap`为闰年标志(0或1)[^3]。 #### 4. 与其他字段的区别 | 字段常量 | 作用 | 示例 (2023-05-15) | |-----------------------|-----------------------|-------------------| | `DAY_OF_MONTH` | 当月第几天 | 15 | | `DAY_OF_YEAR` | 当年第几天 | 135 | | `DAY_OF_WEEK` | 本周第几天 (周日=1) | 2 (周一) | | `DAY_OF_WEEK_IN_MONTH` | 当月第几个星期X | 3 (当月第三个周一)[^1] | #### 5. 注意事项 - **边界处理**:设置超出当月天数的值(如4月31日)会自动转到下月 - **性能优化**:避免在循环中频繁调用,优先使用日期计算库 - **时区影响**:跨时区操作需结合`TimeZone`类处理 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值