//时间选择器库
implementation 'com.contrarywind:Android-PickerView:4.1.6'

//1  时间显示

//private TimePickerView pvTime;
/*** 生日选择器*/private void initLunarPicker() {Calendar selectedDate = Calendar.getInstance();//系统当前时间selectedDate.set(1990, 1, 1);Calendar startDate = Calendar.getInstance();startDate.set(1970, 1, 1);Calendar endDate = Calendar.getInstance();//endDate.set(2069, 2, 28);pvTime = new TimePickerBuilder(this, (date, v) -> {//选中事件回调birth = date;tvBirthday.setText(TimeUtils.getYMDFormat(date));
//                mApplyBlindDateBir.setText(new SimpleDateFormat("yyyy-MM-dd").format(date));}).setDate(selectedDate).setRangDate(startDate, endDate).setContentTextSize(18).setType(new boolean[]{true, true, true, false, false, false}).setLabel("年", "月", "日", null, null, null).setLineSpacingMultiplier(1.2f).setTextXOffset(0, 0, 0, 40, 0, -40).isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。.build();}
 if (pvTime != null) {pvTime.show();}

//2 条件选择

//条件选择器OptionsPickerView pvOptions = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {@Overridepublic 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);pvNoLinkOptions.setSelectOptions(1, 1);pvOptions.show(); 

https://www.cnblogs.com/whycxb/p/9163456.html

比较好的讲解链接

效果图

使用步骤

一、项目组织结构图

package com.why.project.pickerviewdemo;import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
import com.bigkoo.pickerview.builder.TimePickerBuilder;
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.why.project.pickerviewdemo.bean.SpinnearBean;
import com.why.project.pickerviewdemo.util.DateTimeHelper;import org.json.JSONArray;
import org.json.JSONObject;import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;public class MainActivity extends AppCompatActivity {private TextView hobbyTv;//选择爱好/**爱好列表集合*/private ArrayList<SpinnearBean> mHobbyList;private ArrayList<String> mHobbyNameList;//用于选择器显示private OptionsPickerView mHobbyPickerView;//选择器private TextView addressTv;//选择地址/**地址列表集合*/private ArrayList<SpinnearBean> mAddressList;private ArrayList<String> mAddressNameList;//用于选择器显示private OptionsPickerView mAddressPickerView;//选择器private TextView startdateTv;//开始日期private TimePickerView mStartDatePickerView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();initDatas();initEvents();}private void initViews() {hobbyTv = findViewById(R.id.hobbyTv);addressTv = (TextView) findViewById(R.id.addressTv);//实现文本区域可滑动的效果,用于当显示的文本过长时addressTv.setMovementMethod(ScrollingMovementMethod.getInstance());//实现可滑动,但是和ScrollView滑动冲突,需要处理下//https://blog.csdn.net/qq_36070190/article/details/70053228addressTv.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubif(event.getAction()==MotionEvent.ACTION_DOWN){//通知父控件不要干扰v.getParent().requestDisallowInterceptTouchEvent(true);}if(event.getAction()==MotionEvent.ACTION_MOVE){//通知父控件不要干扰v.getParent().requestDisallowInterceptTouchEvent(true);}if(event.getAction()==MotionEvent.ACTION_UP){v.getParent().requestDisallowInterceptTouchEvent(false);}return false;}});startdateTv = findViewById(R.id.startdateTv);}private void initDatas() {//========================================初始化爱好列表集合========================================mHobbyList = new ArrayList<SpinnearBean>();mHobbyNameList = new ArrayList<String>();//模拟获取数据集合try{mHobbyList = parseJsonArray("spinners.txt");}catch (Exception e) {e.printStackTrace();}for(SpinnearBean spinnearBean : mHobbyList){mHobbyNameList.add(spinnearBean.getParaName());}//============初始化选择器============initHobbyOptionPicker();//如果想要直接赋值的话,这样写/*if(mHobbyNameList.size() > 0){hobbyTv.setText(mHobbyNameList.get(0));//默认展现第一个}*///========================================初始化地址列表集合========================================mAddressList = new ArrayList<SpinnearBean>();mAddressNameList = new ArrayList<String>();//模拟获取数据集合try{mAddressList = parseJsonArray("spinners2.txt");}catch (Exception e) {e.printStackTrace();}for(SpinnearBean spinnearBean : mAddressList){mAddressNameList.add(spinnearBean.getParaName());}//============初始化选择器============initAddressOptionPicker();//当选择器列表项文本过长时,直接赋值的话,会有问题:高度变小了。不太明白什么原因,所以需要延迟设置文本,实际过程中因为有网络请求,所以一般没有问题/*new Handler().postDelayed(new Runnable() {@Overridepublic void run() {if(mAddressNameList.size() > 0){addressTv.setText(mAddressNameList.get(0));//默认展现第一个}}}, 500);*///========================================初始化开始日期选择器控件========================================initStartTimePicker();//初始化开始日期选择器控件}//初始化爱好选择器private void initHobbyOptionPicker() {mHobbyPickerView = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {@Overridepublic void onOptionsSelect(int options1, int option2, int options3, View v) {//返回的分别是三个级别的选中位置String tx = mHobbyNameList.get(options1);hobbyTv.setText(tx);}}).setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域.setTitleText("选择爱好")//标题文字.setTitleSize(20)//标题文字大小.setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色.setCancelText("取消")//取消按钮文字.setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色.setSubmitText("确定")//确认按钮文字.setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色.setContentTextSize(20)//滚轮文字大小.setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值.setLineSpacingMultiplier(1.8f)//行间距.setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色.setSelectOptions(0)//设置选择的值.build();mHobbyPickerView.setPicker(mHobbyNameList);//添加数据}//初始化地址选择器private void initAddressOptionPicker() {mAddressPickerView = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {@Overridepublic void onOptionsSelect(int options1, int option2, int options3, View v) {//返回的分别是三个级别的选中位置String tx = mAddressNameList.get(options1);addressTv.setText(tx);}}).setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域.setTitleText("选择地址")//标题文字.setTitleSize(20)//标题文字大小.setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色.setCancelText("取消")//取消按钮文字.setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色.setSubmitText("确定")//确认按钮文字.setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色.setContentTextSize(20)//滚轮文字大小.setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值.setLineSpacingMultiplier(1.8f)//行间距.setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色.setSelectOptions(0)//设置选择的值.build();mAddressPickerView.setPicker(mAddressNameList);//添加数据}/**初始化开始日期选择器控件*/private void initStartTimePicker() {//控制时间范围(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释)//因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11Calendar selectedDate = Calendar.getInstance();//设置最小日期和最大日期Calendar startDate = Calendar.getInstance();try {startDate.setTime(DateTimeHelper.parseStringToDate("1970-01-01"));//设置为2006年4月28日} catch (ParseException e) {e.printStackTrace();}Calendar endDate = Calendar.getInstance();//最大日期是今天//时间选择器mStartDatePickerView = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() {@Overridepublic void onTimeSelect(Date date, View v) {//选中事件回调// 这里回调过来的v,就是show()方法里面所添加的 View 参数,如果show的时候没有添加参数,v则为nullstartdateTv.setText(DateTimeHelper.formatToString(date,"yyyy-MM-dd"));}}).setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域//年月日时分秒 的显示与否,不设置则默认全部显示.setType(new boolean[]{true, true, true, false, false, false}).setLabel("", "", "", "", "", "").isCenterLabel(false)//是否只显示中间选中项的label文字,false则每项item全部都带有label。.setTitleText("开始日期")//标题文字.setTitleSize(20)//标题文字大小.setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色.setCancelText("取消")//取消按钮文字.setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色.setSubmitText("确定")//确认按钮文字.setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色.setContentTextSize(20)//滚轮文字大小.setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值.setLineSpacingMultiplier(1.8f)//行间距.setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色.setRangDate(startDate, endDate)//设置最小和最大日期.setDate(selectedDate)//设置选中的日期.build();}private void initEvents() {//选择爱好的下拉菜单点击事件hobbyTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mHobbyPickerView.show();}});//选择地址的下拉菜单点击事件addressTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mAddressPickerView.show();}});//开始日期的下拉菜单点击事件startdateTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mStartDatePickerView.show();}});}/*===========读取assets目录下的js字符串文件(js数组和js对象),然后生成List集合===========*/public static final String LISTROOTNODE = "spinnerList";public static final String KEY_LISTITEM_NAME = "paraName";public static final String KEY_LISTITEM_VALUE = "paraValue";public static final String KEY_LISTITEM_CHECKCOLOR = "checkColor";/*** 解析JSON文件的简单数组*/private ArrayList<SpinnearBean> parseJsonArray(String fileName) throws Exception{ArrayList<SpinnearBean> itemsList = new ArrayList<SpinnearBean>();String jsonStr = getStringFromAssert(MainActivity.this, fileName);if(jsonStr.equals("")){return null;}JSONObject allData = new JSONObject(jsonStr);  //全部内容变为一个项JSONArray jsonArr = allData.getJSONArray(LISTROOTNODE); //取出数组for(int x = 0;x<jsonArr.length();x++){SpinnearBean model = new SpinnearBean();JSONObject jsonobj = jsonArr.getJSONObject(x);model.setParaName(jsonobj.getString(KEY_LISTITEM_NAME));model.setParaValue(jsonobj.getString(KEY_LISTITEM_VALUE));if(jsonobj.has(KEY_LISTITEM_CHECKCOLOR)){model.setCheckColor(jsonobj.getString(KEY_LISTITEM_CHECKCOLOR));}model.setSelectedState(false);itemsList.add(model);model = null;}return itemsList;}/*** 访问assets目录下的资源文件,获取文件中的字符串* @param filePath - 文件的相对路径,例如:"listdata.txt"或者"/www/listdata.txt"* @return 内容字符串* */public String getStringFromAssert(Context mContext, String filePath) {String content = ""; // 结果字符串try {InputStream is = mContext.getResources().getAssets().open(filePath);// 打开文件int ch = 0;ByteArrayOutputStream out = new ByteArrayOutputStream(); // 实现了一个输出流while ((ch = is.read()) != -1) {out.write(ch); // 将指定的字节写入此 byte 数组输出流}byte[] buff = out.toByteArray();// 以 byte 数组的形式返回此输出流的当前内容out.close(); // 关闭流is.close(); // 关闭流content = new String(buff, "UTF-8"); // 设置字符串编码} catch (Exception e) {Toast.makeText(mContext, "对不起,没有找到指定文件!", Toast.LENGTH_SHORT).show();}return content;}
}

通过继承,反射,获取自己想要的样式

 <style name="divider_hor_gray"><item name="android:layout_height">1dp</item><item name="android:layout_width">match_parent</item><item name="android:background">@color/divider_gray</item></style>
/*** 反射 options并修改样式   picker*/
public class MyOptionsPickerBuilder extends OptionsPickerBuilder {//Requiredpublic MyOptionsPickerBuilder(Context context, OnOptionsSelectListener listener) {super(context,listener);// 通过这种方法可以得到父类的所有属性 -→ 先得到父类class 然后class调用getDeclaredFields()方法Class<?> superclass = getClass().getSuperclass();try {Field mFiled = superclass.getDeclaredField("mPickerOptions");mFiled.setAccessible(true);PickerOptions mPickerOptions = (PickerOptions) mFiled.get(this);//1布局修正mPickerOptions.layoutRes = R.layout.my_pickerview_options;//2最大显示条目修正mPickerOptions.itemsVisibleCount = 5;//3当行高度修正mPickerOptions.lineSpacingMultiplier = 3.0f;setTitleBgColor(context.getResources().getColor(R.color.white));} catch (Exception e) {e.printStackTrace();}}
}

上边是OptionsPicker下面介绍TimePicker 自定义

/*** 扩展原来的布局时间选择器布局*/
public class MyTimePickerBuilder extends TimePickerBuilder {private View customView;//Requiredpublic MyTimePickerBuilder(Context context, OnTimeSelectListener listener) {super(context,listener);setLayoutRes(R.layout.my_pickerview_time, v -> customView = v);}/*** 使用通用配置样式  *需要放构造方法后面*/public MyTimePickerBuilder useCommonStyle(Context context){setItemVisibleCount(5);setLineSpacingMultiplier(3.0f);setTitleBgColor(context.getResources().getColor(R.color.white));setCancelColor(context.getResources().getColor(R.color.text_black));//取消按钮文字颜色setSubmitColor(context.getResources().getColor(R.color.text_black));//确定按钮文字颜色return this;}@Overridepublic TimePickerView build() {TimePickerView pickerView = super.build();//使用自定义布局之后,不会再按照options去初始化,需要自己手动添加初始化代码if (customView != null)initCustomView(customView, pickerView);return pickerView;}/***反射options 按照options去初始化* @param view 自定义view* @param listener  还原原来的布局初始化*/private void initCustomView(@NonNull View view,View.OnClickListener listener){//顶部标题TextView tvTitle =  view.findViewById(R.id.tvTitle);RelativeLayout rv_top_bar =  view.findViewById(R.id.rv_topbar);//确定和取消按钮Button btnSubmit =  view.findViewById(R.id.btnSubmit);Button btnCancel =  view.findViewById(R.id.btnCancel);//TimePickerView 中一摸一样才行,取消,确定根据的是这两个tag 自定义View不设置会空指针String TAG_SUBMIT = "submit";String TAG_CANCEL = "cancel";btnSubmit.setTag(TAG_SUBMIT);btnCancel.setTag(TAG_CANCEL);btnSubmit.setOnClickListener(listener);btnCancel.setOnClickListener(listener);// 通过这种方法可以得到父类的所有属性 -→ 先得到父类class 然后class调用getDeclaredFields()方法Class<?> superclass = getClass().getSuperclass();try {if (superclass == null) return;Field mFiled = superclass.getDeclaredField("mPickerOptions");mFiled.setAccessible(true);PickerOptions mPickerOptions = (PickerOptions) mFiled.get(this);//设置文字btnSubmit.setText(TextUtils.isEmpty(mPickerOptions.textContentConfirm) ? mPickerOptions.context.getResources().getString(R.string.pickerview_submit) : mPickerOptions.textContentConfirm);btnCancel.setText(TextUtils.isEmpty(mPickerOptions.textContentCancel) ? mPickerOptions.context.getResources().getString(R.string.pickerview_cancel) : mPickerOptions.textContentCancel);tvTitle.setText(TextUtils.isEmpty(mPickerOptions.textContentTitle) ? "" : mPickerOptions.textContentTitle);//默认为空//设置colorbtnSubmit.setTextColor(mPickerOptions.textColorConfirm);btnCancel.setTextColor(mPickerOptions.textColorCancel);tvTitle.setTextColor(mPickerOptions.textColorTitle);rv_top_bar.setBackgroundColor(mPickerOptions.bgColorTitle);//设置文字大小btnSubmit.setTextSize(mPickerOptions.textSizeSubmitCancel);btnCancel.setTextSize(mPickerOptions.textSizeSubmitCancel);tvTitle.setTextSize(mPickerOptions.textSizeTitle);} catch (Exception e) {e.printStackTrace();}}
}

自定义布局

private void initCustomOptionPicker() {//条件选择器初始化,自定义布局/*** @description** 注意事项:* 自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针。* 具体可参考demo 里面的两个自定义layout布局。*/pvCustomOptions = new OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onClick(View v) {pvCustomOptions.returnData();pvCustomOptions.dismiss();}});ivCancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {pvCustomOptions.dismiss();}});tvAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getCardData();pvCustomOptions.setPicker(cardItem);}});}}).isDialog(true).build();pvCustomOptions.setPicker(cardItem);//添加数据}

PickerView 时间/城市联动选择器TimePickerBuilder+OptionsPickerBuilder相关推荐

  1. android双日期选择器,AndroidPicker 安卓选择器类库,包括日期选择器、时间选择器、单项选择器、双项选择器、城市地址选择器、车牌号选择器 @codeKK Android开源站...

    安卓选择器类库,包括日期及时间选择器(可设置范围).单项选择器(可用于性别.职业.学历.星座等).城市地址选择器(分省级.地级及县级).数字选择器(可用于年龄.身高.体重.温度等).双项选择器.颜色选 ...

  2. 如何造一个移动端的联动选择器(三)

    之前写了一篇 MultiPicker -『为移动端而生』的自定义多级联动选择器,得到了很多人的关注.鉴于很多人对这种手写插件的过程很好奇,所以写了几篇文章,来说说它的成长史~ 这一阶段,你将会了解到页 ...

  3. JavaScript 日期联动选择器

    一个日期联动选择器,年月日联动显示,准确显示日期(包括闰年日期),可自定义日期范围. 效果预览:   程序说明 [select] 先说清空一个select,最简单的方法是把options的length ...

  4. php ajax城市联动,php+ajax 城市联动

    jquery-1.8.0.min.js 自己下载 /*  表结构 -- -- 表的结构 `web_city` -- CREATE TABLE IF NOT EXISTS `web_city` ( `i ...

  5. range 小程序picker_微信小程序-官方组件picker云开发省市区三级联动选择器

    早在一年多以前,我写过一篇微信小程序-省市区县三级联动选择器的文章,那时候小程序刚起步,网上找了很久没有相关的文献,官方也没有相关的组件,我就自己动手写了一个,也因为刚开始接触写的不是很好. 当时省市 ...

  6. 通过城市联动实时将地址显示到text中

    <div class="form-group field-supplier-sort <?php if($model->getErrors('province_id') | ...

  7. 省份城市联动 多选

    实现省份城市联动,多选(checkbox) <!DOCTYPE html> <html> <head> <meta http-equiv="Cont ...

  8. 事件练习正反选,二级城市联动,下拉菜单练习

    正反选 [HTML页面] <!DOCTYPE html> <html lang="en"> <head><meta charset=&qu ...

  9. js实现全国三级城市联动select选择

    /* * 全国三级城市联动 js版 */ function Dsy(){this.Items = {}; } Dsy.prototype.add = function(id,iArray){this. ...

最新文章

  1. 2022-2028中国曝光机市场现状及未来发展趋势
  2. JS获取HTML元素属性【转】
  3. node.js Web应用框架Express入门指南
  4. Oracle绝对值函数
  5. Instagram视频上传延迟优化
  6. html5中的一些标签学习总结
  7. JIURL文档-Linux的虚拟内存与分页机制(x86-64位)(一)
  8. redhat linux配置RSH遇见的问题
  9. python入门教程(非常详细)-python初学者怎么入门:python入门教程非常详细
  10. sql两张表,分组或row_number()取最新的记录SQL
  11. 使用非参数统计检验进行分析的指南
  12. 腾讯视频qlv格式转换mp4普通视频方法
  13. 中国互联网史就是一部流氓史!
  14. VB中的“msgbox”函数各参数详解
  15. 基于python的图片比较
  16. 3D建模教程讲解!PBR场景制作破损的图书馆
  17. C++ Primer 读书笔记及知识点延伸 chapter1
  18. [TOG2019]Deferred Neural Rendering:Image Synthesis using Neural Textures
  19. guacamole SSH、TELNET建议配置中文无衬线等宽字体Noto Sans Mono CJK SC
  20. 技术博客丨原来模型训练可以不用标注?一文全解四大机器学习方法

热门文章

  1. 感情沟通出了问题要怎么解决_当感情出现问题怎么沟通 相处更融洽
  2. 计算机三十首音乐是什么歌曲,2020开车必听歌曲排行榜 车上常放的三十首歌曲...
  3. War3 局域网开局地图校验机制分析
  4. i99980hk和9900k哪个好?有什么区别?
  5. 5 个需要知道的开源的软件定义网络(SDN)项目
  6. I.MX RT1052核心板
  7. [置顶]       读书笔记之《格蠹汇编-软件调试案例集锦》
  8. 菜鸟好文推荐(六)——加班是什麼,可以吃嗎?
  9. 笔记:APDrawingGAN: Generating Artistic Portrait Drawings From Face Photos With Hierarchical GANs
  10. 强制删除密保的symantec