《码农翻身:用故事给技术加点料》
《码农翻身:用故事给技术加点料》
《码农翻身:用故事给技术加点料》
Android选择器PickerView
https://github.com/Bigkoo/Android-PickerView
Wiki文档,Wiki文档,Wiki文档 !~ 重要的事情说三遍
这是一款仿iOS的PickerView控件,有时间选择器和选项选择器,新版本的详细特性如下:
——TimePickerView 时间选择器,支持年月日时分,年月日,年月,时分等格式。
——OptionsPickerView 选项选择器,支持一,二,三级选项选择,并且可以设置是否联动 。
正确使用案例:
startDate.set(2013,0,1);
endDate.set(2020,11,1);
#### V4.1.9 版本更新说明(2019-10-20)
#### V4.1.8 版本更新说明(2019-4-24)
#### V4.1.7 版本更新说明(2019-1-10)
compile 'com.contrarywind:Android-PickerView:4.1.8'
或者
<dependency>
<groupId>com.contrarywind</groupId>
<artifactId>Android-PickerView</artifactId>
<version>4.1.8</version>
<type>pom</type>
</dependency>
//时间选择器
TimePickerView pvTime = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date, View v) {
Toast.makeText(MainActivity.this, getTime(date), Toast.LENGTH_SHORT).show();
}
}).build();
//条件选择器
OptionsPickerView pvOptions = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
//返回的分别是三个级别的选中位置
String tx = options1Items.get(options1).getPickerViewText()
+ options2Items.get(options1).get(option2)
+ options3Items.get(options1).get(option2).get(options3).getPickerViewText();
tvOptions.setText(tx);
}
}).build();
pvOptions.setPicker(options1Items, options2Items, options3Items);
pvOptions.show();
Calendar selectedDate = Calendar.getInstance();
Calendar startDate = Calendar.getInstance();
//startDate.set(2013,1,1);
Calendar endDate = Calendar.getInstance();
//endDate.set(2020,1,1);
//正确设置方式 原因:注意事项有说明
startDate.set(2013,0,1);
endDate.set(2020,11,31);
pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date,View v) {//选中事件回调
tvTime.setText(getTime(date));
}
})
.setType(new boolean[]{true, true, true, true, true, true})// 默认全部显示
.setCancelText("Cancel")//取消按钮文字
.setSubmitText("Sure")//确认按钮文字
.setContentSize(18)//滚轮文字大小
.setTitleSize(20)//标题文字大小
.setTitleText("Title")//标题文字
.setOutSideCancelable(false)//点击屏幕,点在控件外部范围时,是否取消显示
.isCyclic(true)//是否循环滚动
.setTitleColor(Color.BLACK)//标题文字颜色
.setSubmitColor(Color.BLUE)//确定按钮文字颜色
.setCancelColor(Color.BLUE)//取消按钮文字颜色
.setTitleBgColor(0xFF666666)//标题背景颜色 Night mode
.setBgColor(0xFF333333)//滚轮背景颜色 Night mode
.setDate(selectedDate)// 如果不设置的话,默认是系统时间*/
.setRangDate(startDate,endDate)//起始终止年月日设定
.setLabel("年","月","日","时","分","秒")//默认设置为年月日时分秒
.isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
.isDialog(true)//是否显示为对话框样式
.build();
pvOptions = new OptionsPickerBuilder(this, new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
//返回的分别是三个级别的选中位置
String tx = options1Items.get(options1).getPickerViewText()
+ options2Items.get(options1).get(option2)
+ options3Items.get(options1).get(option2).get(options3).getPickerViewText();
tvOptions.setText(tx);
}
}) .setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
@Override
public void onOptionsSelectChanged(int options1, int options2, int options3) {
String str = "options1: " + options1 + "\noptions2: " + options2 + "\noptions3: " + options3;
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
})
.setSubmitText("确定")//确定按钮文字
.setCancelText("取消")//取消按钮文字
.setTitleText("城市选择")//标题
.setSubCalSize(18)//确定和取消文字大小
.setTitleSize(20)//标题文字大小
.setTitleColor(Color.BLACK)//标题文字颜色
.setSubmitColor(Color.BLUE)//确定按钮文字颜色
.setCancelColor(Color.BLUE)//取消按钮文字颜色
.setTitleBgColor(0xFF333333)//标题背景颜色 Night mode
.setBgColor(0xFF000000)//滚轮背景颜色 Night mode
.setContentTextSize(18)//滚轮文字大小
.setLinkage(false)//设置是否联动,默认true
.setLabels("省", "市", "区")//设置选择的三级单位
.isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
.setCyclic(false, false, false)//循环与否
.setSelectOptions(1, 1, 1) //设置默认选中项
.setOutSideCancelable(false)//点击外部dismiss default true
.isDialog(true)//是否显示为对话框样式
.isRestoreItem(true)//切换时是否还原,设置默认选中第一项。
.build();
pvOptions.setPicker(options1Items, options2Items, options3Items);//添加数据源
// 注意:自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针
// 具体可参考demo 里面的两个自定义布局
pvCustomOptions = new OptionsPickerBuilder(this, new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3, View v) {
//返回的分别是三个级别的选中位置
String tx = cardItem.get(options1).getPickerViewText();
btn_CustomOptions.setText(tx);
}
})
.setLayoutRes(R.layout.pickerview_custom_options, new CustomListener() {
@Override
public void customLayout(View v) {
//自定义布局中的控件初始化及事件处理
final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
final TextView tvAdd = (TextView) v.findViewById(R.id.tv_add);
ImageView ivCancel = (ImageView) v.findViewById(R.id.iv_cancel);
tvSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomOptions.returnData(tvSubmit);
}
});
ivCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomOptions.dismiss();
}
});
tvAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getData();
pvCustomOptions.setPicker(cardItem);
}
});
}
})
.build();
pvCustomOptions.setPicker(cardItem);//添加数据
compile 'com.contrarywind:wheelview:4.0.9'
xml布局:
<com.contrarywind.view.WheelView
android:id="@+id/wheelview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Java 代码:
WheelView wheelView = findViewById(R.id.wheelview);
wheelView.setCyclic(false);
final List<String> mOptionsItems = new ArrayList<>();
mOptionsItems.add("item0");
mOptionsItems.add("item1");
mOptionsItems.add("item2");
wheelView.setAdapter(new ArrayWheelAdapter(mOptionsItems));
wheelView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
Toast.makeText(MainActivity.this, "" + mOptionsItems.get(index), Toast.LENGTH_SHORT).show();
}
});
https://github.com/luxiangqiang/Data-Structure-Coding
tp5备份mysql数据库(备忘)
//数据库备份
public function backups()
{
//1.获取数据库信息
$info = Db::getConfig();
$dbname = $info['database'];
//2.获取数据库所有表
$tables = Db::query("show tables");
//3、组装头部信息
header("Content-type:text/html;charset=utf-8");
$path = ROOT_PATH.'/data/';
$database = $dbname; //获取当前数据库
$info = "-- ----------------------------\r\n";
$info .= "-- 日期:".date("Y-m-d H:i:s",time())."\r\n";
$info .= "-- MySQL - 5.5.52-MariaDB : Database - ".$database."\r\n";
$info .= "-- ----------------------------\r\n\r\n";
$info .= "SET NAMES utf8;\r\nSET FOREIGN_KEY_CHECKS = 0;\r\n\r\n";
//4、检查目录是否存在
if (is_dir($path)) {
if (is_writable($path)) {
} else {
echo '目录不可写'; exit();
}
} else {
mkdir($path,0777,true);
}
//5、保存的文件名称
$file_name = $path.$database.'_'.date('Ymd_His').'.sql';
file_put_contents($file_name, $info, FILE_APPEND);
//6、循环表,写入数据
foreach ($tables as $k => $v) {
$val = $v["Tables_in_$database"];
$sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='$val' AND TABLE_SCHEMA='$dbname'";
$res = Db::query($sql);
$max_num = Db::table("$val")->order('id desc')->value('id');
//查询表结构
$info_table = "-- ----------------------------\r\n";
$info_table .= "-- Table structure for `$val`\r\n";
$info_table .= "-- ----------------------------\r\n\r\n";
$info_table .= "DROP TABLE IF EXISTS `$val`;\r\n";
if (count($res) < 1) {
continue;
}
$info_table .= "CREATE TABLE `$val` (\n\r\t";
foreach ($res as $kk => $vv) {
$info_table .= " `".$vv['COLUMN_NAME']."` ";
$info_table .= $vv['COLUMN_TYPE'];
//是否允许空值
if ($vv['IS_NULLABLE'] == 'NO') {
$info_table .= " NOT NULL ";
}
//判断主键
if ($vv['EXTRA']) {
$info_table .= " AUTO_INCREMENT ";
$key = $vv['COLUMN_NAME'];
}
//编码
if ($vv['CHARACTER_SET_NAME']) {
$info_table .= " CHARACTER SET ".$vv['CHARACTER_SET_NAME'];
}
//字符集
if ($vv['COLLATION_NAME']) {
$info_table .= " COLLATE ".$vv['COLLATION_NAME'];
}
//默认数值
if ($vv['COLUMN_DEFAULT']) {
$info_table .= " DEFAULT ".$vv['COLUMN_DEFAULT'];
}
//注释
if ($vv['COLUMN_COMMENT']) {
$info_table .= " COMMENT '".$vv['COLUMN_COMMENT']."',\n\r\t";
}
}
$info_table .= " PRIMARY KEY (`$key`) USING BTREE";
$info_table .= "\n\r) ENGINE = MyISAM AUTO_INCREMENT $max_num CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;\r\n\r\n";
//查询表数据
$info_table .= "-- ----------------------------\r\n";
$info_table .= "-- Data for the table `$val`\r\n";
$info_table .= "-- ----------------------------\r\n\r\n";
file_put_contents($file_name,$info_table,FILE_APPEND);
$sql_data = "select * from $val";
$data = Db::query($sql_data);
$count= count($data);
if ($count < 1) {
continue;
}
foreach ($data as $key => $value) {
$sqlStr = "INSERT INTO `$val` VALUES (";
foreach($value as $v_d){
$v_d = str_replace("'","\'",$v_d);
$sqlStr .= "'".$v_d."', ";
}
//需要特别注意对数据的单引号进行转义处理
//去掉最后一个逗号和空格
$sqlStr = substr($sqlStr,0,strlen($sqlStr)-2);
$sqlStr .= ");\r\n";
file_put_contents($file_name,$sqlStr,FILE_APPEND);
}
$info = "\r\n";
file_put_contents($file_name,$info,FILE_APPEND);
}
//7、下载数据到本地
ob_end_clean();
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($file_name));
header('Content-Disposition: attachment; filename=' . basename($file_name));
readfile($file_name);
DownloadFile($path.$file_name);
$this->success("数据已备份");
}
前序遍历(先序):前序遍历可以记为根左右,若二叉树为空,则结束返回。
前序遍历的规则:
(1)访问根节点
(2)前序遍历左子树
(3)前序遍历右子树
这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成。
前序遍历的输出结果:ABDECF
中序遍历:中序遍历可以记为左根右,也就是说在二叉树的遍历过程中,首先要遍历二叉树的左子树,接着遍历根节点,最后遍历右子树。
同样,在二叉树为空的时候,结束返回。
中序遍历的规则:
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
注意:在完成第1,3步的时候,要按照中序遍历的规则来完成。
中序遍历的输出结果:DBEAFC
后序遍历:后序遍历可以记为左右根,也就是说在二叉树的遍历过程中,首先按照后序遍历的规则遍历左子树,接着按照后序遍历的规则遍历右子树,最后访问根节点。
在二叉树为空的时候,结束返回。
后序遍历二叉树的规则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
注意:在完成1,2步的时候,依然要按照后序遍历的规则来完成。
后序遍历的输出顺序:DEBFCA