自定义view之超级课程表页面的实现
之前机缘巧合做了一个类似超级课程表app的课程表界面,如图所示界面,特此分享它的实现方式和部分源码。
观察分析课程表,发现它可以按下图所示的方式实现:
一、视图部分的实现:
<1.顶部GridView表示周一到周五,设置numColumns为8,添加的数据为“”、周一到周日,这个很简单。
<2.左侧使用自定义的ListView,表示第几节课,这里自定义的原因是为解决ScrollView内嵌ListView的滑动冲突问题,下面会提供代码。
<3.中间Content部分是课程表的主要部分。我们的实现思路是这样的:
在FrameLayout中填充俩个组件,可以知道这俩个组件是重叠的。
第一个组件是自定义的GridView(原因同上),用于显示背景的课程格子,以及触发用户的点击事件,至于触发结果,就是获取用户当前选择的位置,以及课程内容和时长。
第二个组件是自定义的一个组件,我们起名为MySchedule,它是一个ViewGroup,作用是在背景GridView获取到数据后,将对应的数据以组件(这里是Textview)的形式添加到MySchedule的对应位置中,以达到课程格子的效果。本身他内部是没有任何组件的,也就是透明的。
二、存储部分的实现:
<1.存储方法:存储采用File文件将课程的数据(位置,课程内容,时长)存储在SD卡中。
<2.存储格式:这里使用Json的生成和解析。
三、代码部分。
<1.照旧,因为涉及到存储,记得添加权限。
<2.布局部分:
《2.1 主布局 activty_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/back" android:orientation="vertical" tools:context="monster.schedule.MainActivity"><GridView android:id="@+id/gvDate" android:layout_width="match_parent" android:layout_height="60dp" android:numColumns="8" /><ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none"><LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:weightSum="8"><com.example.administrator.schedule.MyListView android:id="@+id/lvNum" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:divider="@null"></com.example.administrator.schedule.MyListView><FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="7"><com.example.administrator.schedule.MyGridView android:id="@+id/gvContent" android:layout_width="match_parent" android:layout_height="match_parent" android:horizontalSpacing="0dp" android:numColumns="7" android:scrollbars="none" android:verticalSpacing="0dp"></com.example.administrator.schedule.MyGridView><com.example.administrator.schedule.MySchedule android:id="@+id/mySchedule" android:layout_width="match_parent" android:layout_height="match_parent"></com.example.administrator.schedule.MySchedule></FrameLayout></LinearLayout></ScrollView> </LinearLayout>
《2.2 Content_GridView_item布局 item_gv_content.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"><com.example.administrator.schedule.MyCardView android:id="@+id/mcv" android:layout_width="match_parent" android:layout_height="60dp" /> </FrameLayout>
《2.3 顶部GridView_item 布局 item_gv_date.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tvDate" android:textColor="#006699" android:layout_width="match_parent" android:layout_height="60dp" android:gravity="center" android:minHeight="60dp"> </TextView>
《2.4 侧边ListView_item布局 item_lv_num.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tvNum" android:layout_width="match_parent" android:layout_height="60dp" android:gravity="center" android:minHeight="60dp" android:textColor="#006699"></TextView>
《2.5 添加课程的提示Dialog布局 dialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical"><EditText android:id="@+id/etName" android:layout_width="match_parent" android:layout_height="60dp" android:layout_marginLeft="20dp" android:background="#00000000" android:gravity="center_vertical" android:hint="输入课程名字" /><EditText android:id="@+id/etNum" android:layout_width="match_parent" android:layout_height="60dp" android:layout_marginLeft="20dp" android:background="#00000000" android:gravity="center_vertical" android:hint="输入课程时长" android:numeric="integer" /><LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"><Button android:id="@+id/btnSure" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="确认" /><Button android:id="@+id/btnCancel" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="取消" /></LinearLayout> </LinearLayout>
《2.6 编辑课程的提示Dialog布局 dialog_edit.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical"><TextView android:layout_marginLeft="20dp" android:gravity="center_vertical" android:id="@+id/tvContent" android:layout_width="match_parent" android:layout_height="60dp" /><LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"><Button android:id="@+id/btnDele" android:layout_width="0dp" android:layout_height="40dp" android:layout_weight="1" android:text="删除" /><Button android:id="@+id/btnClose" android:layout_width="0dp" android:layout_height="40dp" android:layout_weight="1" android:text="关闭" /></LinearLayout> </LinearLayout>
<3.Java
《1.MainActivity 主要进行存储数据的读取和课程的添加操作
public class MainActivity extends Activity {private GridView gvDate, gvContent;private ListView lvNum;private MySchedule mySchedule;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();//因为重叠,所以可以通过GridView的ItemClick获取当前位置信息,这里传的是position,具体的计算工作交给MySchedule gvContent.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {openAlter(position);}});//打开app,读取存储的课程信息 mySchedule.read();}private void init() {gvDate = (GridView) findViewById(R.id.gvDate);gvDate.setAdapter(new GvDateAdapter(MainActivity.this));lvNum = (ListView) findViewById(R.id.lvNum);lvNum.setAdapter(new LvNumAdapter(MainActivity.this));gvContent = (GridView) findViewById(R.id.gvContent);gvContent.setAdapter(new GvContentAdapter(MainActivity.this));mySchedule = (MySchedule) findViewById(R.id.mySchedule);}//添加组件的dialog private void openAlter(final int position) {final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();alertDialog.show();alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);Window window = alertDialog.getWindow();window.setContentView(R.layout.dialog);final EditText etName = (EditText) window.findViewById(R.id.etName);final EditText etNum = (EditText) window.findViewById(R.id.etNum);Button btnSuer = (Button) window.findViewById(R.id.btnSure);Button btnCancel = (Button) window.findViewById(R.id.btnCancel);btnSuer.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {if (!TextUtils.isEmpty(etName.getText().toString()) && !TextUtils.isEmpty(etNum.getText().toString())) {int num = Integer.valueOf(etNum.getText().toString());if (num <= 12 && num > 0) {Coordinate coordinate = new Coordinate(position, num, etName.getText().toString());//此时是新添加View,所以要先添加进列表,然后显示,最后还要进行数据的保存工作,这些全部在addToList中完成了 mySchedule.addToList(coordinate);alertDialog.dismiss();}}}});btnCancel.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {alertDialog.dismiss();}});} }
《2.自定义的ListView和GridView,用于解决内嵌冲突。
public class MyGridView extends GridView {public MyGridView(Context context, AttributeSet attrs) {super(context, attrs);}public MyGridView(Context context) {super(context);}public MyGridView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
-----------------------------------------------------------------------------
public class MyListView extends ListView {public MyListView(Context context, AttributeSet attrs) {super(context, attrs);}public MyListView(Context context) {super(context);}public MyListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
《3.三个适配器类,用于适配主布局中的Listview和俩个GridView
public class GvContentAdapter extends BaseAdapter {private Context context;private ArrayList<String> list;public GvContentAdapter(Context context) {this.context = context;list = new ArrayList<>();for (int i = 0 ; i < 84;i++){list.add("");}}@Override public int getCount() {return list != null ? list.size() : 0;}@Override public Object getItem(int position) {return null;}@Override public long getItemId(int position) {return 0;}@Override public View getView(int position, View convertView, ViewGroup parent) {ViewHolder vh = null;if (convertView == null) {vh = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item_gv_content, null);vh.mcv = (MyCardView) convertView.findViewById(R.id.mcv);convertView.setTag(vh);} else {vh = (ViewHolder) convertView.getTag();}return convertView;}public static final class ViewHolder {MyCardView mcv;} }
------------------------------------------------------------------------------------------------------ public class GvDateAdapter extends BaseAdapter {private Context context;private ArrayList<String> list;public GvDateAdapter(Context context) {this.context = context;list = new ArrayList<>();list.add("Back");list.add("周一");list.add("周二");list.add("周三");list.add("周四");list.add("周五");list.add("周六");list.add("周日");}@Override public int getCount() {return list != null ? list.size() : 0;}@Override public Object getItem(int position) {return null;}@Override public long getItemId(int position) {return 0;}@Override public View getView(int position, View convertView, ViewGroup parent) {ViewHolder vh = null;if (convertView == null) {vh = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item_gv_date, null);vh.tvDate = (TextView) convertView.findViewById(R.id.tvDate);convertView.setTag(vh);} else {vh = (ViewHolder) convertView.getTag();}vh.tvDate.setText(list.get(position));return convertView;}public static final class ViewHolder {TextView tvDate;} }
------------------------------------------------------------------------------------------------------------------ public class LvNumAdapter extends BaseAdapter {private Context context;private ArrayList<String> list;public LvNumAdapter(Context context) {this.context = context;list = new ArrayList<>();for (int i = 1; i <= 12; i++) {list.add(i + "");}}@Override public int getCount() {return list != null ? list.size() : 0;}@Override public Object getItem(int position) {return null;}@Override public long getItemId(int position) {return 0;}@Override public View getView(int position, View convertView, ViewGroup parent) {ViewHolder vh = null;if (convertView == null) {vh = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item_lv_num, null);vh.tvNum = (TextView) convertView.findViewById(R.id.tvNum);convertView.setTag(vh);} else {vh = (ViewHolder) convertView.getTag();}vh.tvNum.setText(list.get(position));return convertView;}public static final class ViewHolder {TextView tvNum;} }
《4.为了使背景的GridView的item有对应的“+”字符,我们稍微给它的item中的View自定义一下。
public class MyCardView extends TextView {private Paint mPaint;public MyCardView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStrokeWidth(2);mPaint.setAlpha(40);}@Override protected void onDraw(Canvas canvas) {super.onDraw(canvas);int x = getMeasuredWidth() / 2;int y = getMeasuredHeight() / 2;int key = getMeasuredWidth()/18;canvas.drawLine(x - key, y, x + key, y, mPaint);canvas.drawLine(x, y - key, x, y + key, mPaint);} }
《5.用于存储课程信息的Bean类
//这是存储位置信息,课程名称,课程时长的Bean类 public class Coordinate implements Serializable {private int position;private int classNum;private String className;public Coordinate(int position, int classNum, String className) {this.position = position;this.classNum = classNum;this.className = className;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public int getClassNum() {return classNum;}public int getPosition() {return position;}public void setClassNum(int classNum) {this.classNum = classNum;}public void setPosition(int position) {this.position = position;} }
《6.最关键的类,用于实现添加课程格子效果的自定义View---MySchedule
public class MySchedule extends ViewGroup {private Context context;private ArrayList<Coordinate> list;//这个是存储路径,开发者可以自己定义 private static final String file_path = "/schedule.txt";public MySchedule(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;list = new ArrayList<>();}//根据List中存储的课程信息,依次添加TextView @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {int childNum = getChildCount();for (int i = 0; i < childNum; i++) {View child = getChildAt(i);Coordinate child_coordinate = list.get(i);int position = child_coordinate.getPosition();//position是从0开始的 //这个计算的是第几行和第几列,因为一周固定7天,所以这里直接使用了7 int line = position / 7;int vertical = position % 7;//每个课程最小单元格的宽度和高度,注意,这里布局中的GridView和ListView是去除了Divider的 int item_width = getMeasuredWidth() / 7;int item_height = getMeasuredHeight() / 12;//给子View计算位置坐标,分别是左上角和右下角的坐标 int left = vertical * item_width;int top = line * item_height;int right = (vertical + 1) * item_width;int bottom = (line + child_coordinate.getClassNum()) * item_height;child.layout(left + 5, top + 5, right - 5, bottom - 5);}}//外部调用的、用于添加组件(课程)的方法 public void addToList(Coordinate coordinate) {list.add(coordinate);addView(coordinate);save();}//添加视图 // @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void addView(final Coordinate coordinate) {TextView tv = new TextView(context);tv.setText(coordinate.getClassName());tv.setBackgroundColor(randomColor());tv.setGravity(Gravity.CENTER);tv.setTextColor(Color.parseColor("#ffffff"));tv.setAlpha(0.80f); // tv.setElevation(5); tv.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) {openAlter(coordinate.getPosition(), coordinate.getClassName());}});addView(tv);}//移除视图 private void removeView(int position) {for (int i = 0; i < list.size(); i++) {if (list.get(i).getPosition() == position) {list.remove(i);removeView(getChildAt(i));}}save();}//保存信息到sd卡下 public void save() {JSONObject jsonObject = dataCreate(list);File sdDir = null;boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在 if (sdCardExist) {sdDir = Environment.getExternalStorageDirectory();//获取跟目录 FileOutputStream fout = null;//也可以传一个file作为参数 try {fout = new FileOutputStream(sdDir + file_path);byte[] bytes = jsonObject.toString().getBytes();fout.write(bytes);fout.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}//把sd卡下的数据读取到list中,然后一一显示 public void read() {File sdDir = null;boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在 if (sdCardExist) {sdDir = Environment.getExternalStorageDirectory();//获取跟目录 File file = new File(sdDir + file_path);if (!file.exists()) {return;}FileInputStream fin = null;try {fin = new FileInputStream(sdDir + file_path);int length = fin.available();byte[] buffer = new byte[length];fin.read(buffer);String res = new String(buffer, "utf-8");fin.close();dataParse(res);//此时已经将读取的数据全部存入到list中,只需要将list中的view显示出来就可,不需要保存 for (int i = 0; i < list.size(); i++) {addView(list.get(i));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}//随机生成颜色 private int randomColor() {Random rnd = new Random();return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));}//编辑dialog,开发者可以自行添加一些方法,比如修改 private void openAlter(final int position, String text) {final AlertDialog alertDialog = new AlertDialog.Builder(context).create();alertDialog.show();alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);Window window = alertDialog.getWindow();window.setContentView(R.layout.dialog_edit);TextView tvContent = (TextView) window.findViewById(R.id.tvContent);tvContent.setText(text);Button btnDele = (Button) window.findViewById(R.id.btnDele);Button btnClose = (Button) window.findViewById(R.id.btnClose);btnDele.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {removeView(position);alertDialog.dismiss();}});btnClose.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {alertDialog.dismiss();}});}//Json文件的生成 private JSONObject dataCreate(ArrayList<Coordinate> coordinates) {JSONObject jsonObject = new JSONObject();try {JSONArray jsonArray = new JSONArray();for (int i = 0; i < coordinates.size(); i++) {JSONObject object = new JSONObject();object.put("position", coordinates.get(i).getPosition());object.put("classNum", coordinates.get(i).getClassNum());object.put("className", coordinates.get(i).getClassName());jsonArray.put(i, object);}jsonObject.put("coordinate", jsonArray);} catch (JSONException e) {e.printStackTrace();}return jsonObject;}//Json文件的解析 private void dataParse(String data) {try {JSONObject jsonObject = new JSONObject(data);JSONArray jsonArray = jsonObject.optJSONArray("coordinate");for (int i = 0; i < jsonArray.length(); i++) {JSONObject object = (JSONObject) jsonArray.optJSONObject(i);Coordinate coordinate = new Coordinate(object.optInt("position"),object.optInt("classNum"),object.optString("className"));list.add(coordinate);}} catch (JSONException e) {e.printStackTrace();}} }
最后附背景图一张,这样我们就做出了仿超级课程表页面的课程表。注意变更xml中的自定义组件名。
顶部采用GridView,侧边采用ListView是为了方便扩展。
为了更加美观,边框样式可以通过自定义item组件来实现多种多样的效果,dialog也如此,由于这里主讲的是实现方式,所以就不赘述了。
自定义view之超级课程表页面的实现相关推荐
- 用HTML写一个超级课程表页面
用HTML写一个超级课程表页面 首先给大家展示一下效果图,他家可以根据自己的喜好,换成自己喜欢的颜色 看到这个图可以把它肯成一个大的表格来进行做,将一些单元格进行相应的合并就可以达到上面所期望的图片效 ...
- HTML——超级课程表页面制作
方法: 借助html,css相关知识制作. 1.用表格来做主体设计,相同课程使之显示效果相同. 2.使用属性选择器将相同课程的效果同化 <!DOCTYPE html> <html l ...
- Android开发之自定义view预览不显示的问题
老套路上图看: 如何解决呢?只需要我们点击右上角的感叹号查看不显示的原因即可 3.查看不显示的原因 4.查看具体报错代码以及报错解决方法 5.自行排查自定义view中有哪些没有初始化的数据进行修改或者 ...
- 支付宝芝麻信用页面自定义View的简单制作(续)
前两个月刚刚写了一篇关于支付宝芝麻信用页面自定义View的总结,感觉写的不太好,链接如下: http://blog.csdn.net/anny_lin/article/details/49474555 ...
- 模仿超级课程表——抓取学校课表数据
本文参考自:打造超级课程表 一.显示课表页面的制作 ①.介绍 用过的超标的同学都知道,超标的课表页面是可以滑动的,并且背景为透明色,可以任意修改背景. 效果展示: ②.制作流程 那么如何制作出这样的表 ...
- 实现-超级课程表——校园登录(2)
课表是在一张table里的,提取table里的内容进行解析,解析方法不止一种,我在解析过程中也尝试了多种方法,直接看代码把 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- android 项目实战——打造超级课程表一键提取课表功能
转载文章请注明来自http://blog.csdn.net/sbsujjbcy 如果你是在校大学生,或许你用多了各种课程表,比如课程格子,超级课程表.它们都有一个共同点就是可以一键导入教务处的课程.那 ...
- php模拟超级课程表,一个功能完善、UI简洁的仿超级课程表的课表控件 TimetableView...
TimetableView 一个非常漂亮的Android课程表控件,该控件支持的功能: 设置数据源 颜色设置,控件内置17种颜色 触感反馈,每种内置颜色都有对应的三个样式 日期显示与高亮 课表Item ...
- 实践--课程表(仿超级课程表展示课表)
总览 在上一篇博客实践–课程表(ViewPager实现)中已经实现了课表内容的获取和展示,可是因为ViewPager的显示的效果的局限性,对于课表的一览性较差.而且没有单双周的区分,不能实时显示,故将 ...
最新文章
- Xamarin提示Build-tools版本过老
- C#-异步Ping检查网络通断
- 用PC端Chrome浏览器进行模拟微信浏览器的开发
- android studio- java注释自己动手弄起来
- 云原生时代业务架构的变革:从单体迈向Serverless
- 云转型谈何容易?打破转型阵痛,汇量科技加码云原生
- (软件工程复习核心重点)第十二章软件项目管理-第四节:软件配置管理和能力成熟度模型
- android 上下滑动重影
- html布局四个正方形,分享一个css小技巧,实现给正方形的四个角设置小方块的方法...
- windows 2013 datacenter 安装sql server2008 r2兼容性
- C语言获取窗口输入焦点,使按钮获得输入焦点 - rainbowcode的个人空间 - OSCHINA - 中文开源技术交流社区...
- 目前SolidWorks软件哪个版本比较好用?更稳定一些?
- SECURITY:补丁
- 基于互联网位置数据的通勤特征挖掘技术
- python中单引号的作用_python里的单引号和双引号的有什么作用
- 【Firefly云手机】最高可虚拟720台手机,支持一键操控,应用多开
- 双通道5.2GSPS(或单通道10.4GSPS)射频采样FMC+模块
- 安卓开发——android8.0应用崩溃,报错: Only fullscreen opaque activities can request orientation
- Oracle数据字典一致性鉴别
- 客户端专项测试-启动时间测试
热门文章
- MVC框架实现用户登录注册功能(连接数据库)
- sugarcrm php版本,CentOS 5.8安装SugarCRM 6.5版本
- python小游戏毕设 炸弹人小游戏设计与实现 (源码)
- AS实现联系人功能 Contact
- FIT5217 Natural language processing学习经验贴
- 10岁小孩通过编程成为CEO,零基础学IT真的不难
- 访问共享目录,取消默认使用Guest帐号登录的解决方法
- OpenCV图像处理(十二)---图像阈值化
- 用IE临时文件夹获取Flash
- 汇川变频器md380量产矢量源码