Android-图片填色
目标效果:
该代码参考鸿洋大神的代码,并进行后期的整理修改。默认为随机填色,如果选择了颜色可以进行指定颜色填充,但填色边的效果暂时还不知道是什么原因。
1.values文件夹中新建attrs.xml页面,自定义属性。
attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="ColourImageView"><attr name="border_color" format="color|reference"></attr></declare-styleable>
</resources>
2.新建MyRadioGroup.java页面,重写RadioGroup控件,解决多行多列的单选按钮点击问题。
MyRadioGroup.java页面:
package com.example.weixu.view;import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;import java.util.ArrayList;
import java.util.HashMap;/*** Created by Dustray on 2017/4/8 0008.*/public class MyRadioGroup extends LinearLayout {private static final String TAG = MyRadioGroup.class.getSimpleName();// holds the checked id; the selection is empty by defaultprivate int mCheckedId = -1;// tracks children radio buttons checked stateprivate CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener;// when true, mOnCheckedChangeListener discards eventsprivate boolean mProtectFromCheckedChange = false;private OnCheckedChangeListener mOnCheckedChangeListener;private PassThroughHierarchyChangeListener mPassThroughListener;private HashMap<Integer, RadioButton> mRadioButtons = new HashMap<>();/*** {@inheritDoc}*/public MyRadioGroup(Context context) {super(context);setOrientation(VERTICAL);init();}/*** {@inheritDoc}*/public MyRadioGroup(Context context, AttributeSet attrs) {super(context, attrs);int orientation = this.getOrientation();setOrientation(orientation);init();}private void init() {mChildOnCheckedChangeListener = new CheckedStateTracker();mPassThroughListener = new PassThroughHierarchyChangeListener();super.setOnHierarchyChangeListener(mPassThroughListener);}/*** {@inheritDoc}*/@Overridepublic void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {// the user listener is delegated to our pass-through listenermPassThroughListener.mOnHierarchyChangeListener = listener;}/*** {@inheritDoc}*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();// checks the appropriate radio button as requested in the XML fileif (mCheckedId != -1) {mProtectFromCheckedChange = true;setCheckedStateForView(mCheckedId, true);mProtectFromCheckedChange = false;setCheckedId(mCheckedId);}}@Overridepublic void addView(View child, int index, ViewGroup.LayoutParams params) {if (child instanceof RadioButton) {final RadioButton button = (RadioButton) child;if (button.isChecked()) {mProtectFromCheckedChange = true;if (mCheckedId != -1) {setCheckedStateForView(mCheckedId, false);}mProtectFromCheckedChange = false;setCheckedId(button.getId());}}super.addView(child, index, params);}/*** <p>Sets the selection to the radio button whose identifier is passed in* parameter. Using -1 as the selection identifier clears the selection;* such an operation is equivalent to invoking {@link #clearCheck()}.</p>** @param id the unique id of the radio button to select in this group** @see #getCheckedRadioButtonId()* @see #clearCheck()*/public void check(int id) {// don't even botherif (id != -1 && (id == mCheckedId)) {return;}if (mCheckedId != -1) {setCheckedStateForView(mCheckedId, false);}if (id != -1) {setCheckedStateForView(id, true);}setCheckedId(id);}private void setCheckedId(int id) {mCheckedId = id;if (mOnCheckedChangeListener != null) {mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);}}private void setCheckedStateForView(int viewId, boolean checked) {View checkedView = findViewById(viewId);if (checkedView != null && checkedView instanceof RadioButton) {((RadioButton) checkedView).setChecked(checked);}}/*** <p>Returns the identifier of the selected radio button in this group.* Upon empty selection, the returned value is -1.</p>** @return the unique id of the selected radio button in this group** @see #check(int)* @see #clearCheck()** @attr ref android.R.styleable#RadioGroup_checkedButton*/public int getCheckedRadioButtonId() {return mCheckedId;}/*** <p>Clears the selection. When the selection is cleared, no radio button* in this group is selected and {@link #getCheckedRadioButtonId()} returns* null.</p>** @see #check(int)* @see #getCheckedRadioButtonId()*/public void clearCheck() {check(-1);}/*** <p>Register a callback to be invoked when the checked radio button* changes in this group.</p>** @param listener the callback to call on checked state change*/public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {mOnCheckedChangeListener = listener;}/*** {@inheritDoc}*/@Overridepublic LayoutParams generateLayoutParams(AttributeSet attrs) {return new LayoutParams(getContext(), attrs);}/*** {@inheritDoc}*/@Overrideprotected boolean checkLayoutParams(ViewGroup.LayoutParams p) {return p instanceof LayoutParams;}@Overrideprotected LinearLayout.LayoutParams generateDefaultLayoutParams() {return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);}@Overridepublic void onInitializeAccessibilityEvent(AccessibilityEvent event) {super.onInitializeAccessibilityEvent(event);event.setClassName(MyRadioGroup.class.getName());}@Overridepublic void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {super.onInitializeAccessibilityNodeInfo(info);info.setClassName(MyRadioGroup.class.getName());}public static class LayoutParams extends LinearLayout.LayoutParams {/*** {@inheritDoc}*/public LayoutParams(Context c, AttributeSet attrs) {super(c, attrs);}/*** {@inheritDoc}*/public LayoutParams(int w, int h) {super(w, h);}/*** {@inheritDoc}*/public LayoutParams(int w, int h, float initWeight) {super(w, h, initWeight);}/*** {@inheritDoc}*/public LayoutParams(ViewGroup.LayoutParams p) {super(p);}/*** {@inheritDoc}*/public LayoutParams(MarginLayoutParams source) {super(source);}/*** <p>Fixes the child's width to* {@link ViewGroup.LayoutParams#WRAP_CONTENT} and the child's* height to {@link ViewGroup.LayoutParams#WRAP_CONTENT}* when not specified in the XML file.</p>** @param a the styled attributes set* @param widthAttr the width attribute to fetch* @param heightAttr the height attribute to fetch*/@Overrideprotected void setBaseAttributes(TypedArray a,int widthAttr, int heightAttr) {if (a.hasValue(widthAttr)) {width = a.getLayoutDimension(widthAttr, "layout_width");} else {width = WRAP_CONTENT;}if (a.hasValue(heightAttr)) {height = a.getLayoutDimension(heightAttr, "layout_height");} else {height = WRAP_CONTENT;}}}/*** <p>Interface definition for a callback to be invoked when the checked* radio button changed in this group.</p>*/public interface OnCheckedChangeListener {/*** <p>Called when the checked radio button has changed. When the* selection is cleared, checkedId is -1.</p>** @param group the group in which the checked radio button has changed* @param checkedId the unique identifier of the newly checked radio button*/public void onCheckedChanged(MyRadioGroup group, int checkedId);}private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// prevents from infinite recursionif (mProtectFromCheckedChange) {return;}mProtectFromCheckedChange = true;if (mCheckedId != -1) {setCheckedStateForView(mCheckedId, false);}mProtectFromCheckedChange = false;int id = buttonView.getId();setCheckedId(id);}}public RadioButton getRadioButtonByCheckedId(int checkedId){return mRadioButtons.get(checkedId);}/*** <p>A pass-through listener acts upon the events and dispatches them* to another listener. This allows the table layout to set its own internal* hierarchy change listener without preventing the user to setup his.</p>*/private class PassThroughHierarchyChangeListener implementsOnHierarchyChangeListener {private OnHierarchyChangeListener mOnHierarchyChangeListener;private int checkedCount = 0;/*** 找到布局下所有RadioButton* @param vg* @return*/public ArrayList<RadioButton> findRadioButtons(ViewGroup vg) {ArrayList<RadioButton> set = new ArrayList<>();int count = vg.getChildCount();for (int i = 0 ; i < count ; i ++) {View view = vg.getChildAt(i);if (view instanceof RadioButton) {set.add(((RadioButton) view));} else if (view instanceof ViewGroup){set.addAll(findRadioButtons((ViewGroup) view));}}return set;}/*** 为RadioButton设置id和监听器* @param rb*/public void setIdAndOnCheckedChangeListener(RadioButton rb){int id = rb.getId();if (id == View.NO_ID) {id = View.generateViewId();rb.setId(id);}rb.setOnCheckedChangeListener( mChildOnCheckedChangeListener);if (rb.isChecked()) {if (checkedCount ++ > 1) {Log.e(TAG, "You can only select one RadioButton");}mCheckedId = rb.getId();}if (checkedCount > 1) {MyRadioGroup.this.removeAllViews();}mRadioButtons.put(id, rb);}/*** {@inheritDoc}*/public void onChildViewAdded(View parent, View child) {if (parent == MyRadioGroup.this && child instanceof RadioButton) {setIdAndOnCheckedChangeListener((RadioButton) child);} else if (parent == MyRadioGroup.this && child instanceof ViewGroup) {ArrayList<RadioButton> hs = findRadioButtons((ViewGroup) child);for (RadioButton rb : hs) {setIdAndOnCheckedChangeListener(rb);}}if (mOnHierarchyChangeListener != null) {mOnHierarchyChangeListener.onChildViewAdded(parent, child);}}/*** {@inheritDoc}*/public void onChildViewRemoved(View parent, View child) {if (parent == MyRadioGroup.this && child instanceof RadioButton) {((RadioButton) child).setOnCheckedChangeListener(null);}if (mOnHierarchyChangeListener != null) {mOnHierarchyChangeListener.onChildViewRemoved(parent, child);}}}
}
package com.example.weixu.view;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.support.v7.widget.AppCompatImageView;
import android.util.Log;
import android.view.MotionEvent;import com.example.weixu.munal.R;import java.util.Random;
import java.util.Stack;/*** Created by weixu on 2017/4/8.*/public class ColourImageView extends AppCompatImageView {private int myColor; //接收选择的颜色private boolean myColorType; //判断是否选择颜色,选择为true,未选择为falsepublic void setMyColor(int myColor) {this.myColor = myColor;}public void setMyColorType(boolean myColorType) {this.myColorType = myColorType;}private Bitmap mBitmap;//边界颜色private int mBorderColor = -1;private boolean hasBorderColor = false;private Stack<Point> mStacks = new Stack<Point>(); //栈public ColourImageView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColourImageView); //用于自定义属性mBorderColor = ta.getColor(R.styleable.ColourImageView_border_color, -1);hasBorderColor = (mBorderColor != -1);ta.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);int viewWidth = getMeasuredWidth();//以宽度为标准,等比例缩放view的高度setMeasuredDimension(viewWidth,getDrawable().getIntrinsicHeight() * viewWidth / getDrawable().getIntrinsicWidth());//根据drawable,去得到一个和view一样大小的bitmapBitmapDrawable drawable = (BitmapDrawable) getDrawable();Bitmap bm = drawable.getBitmap();mBitmap = Bitmap.createScaledBitmap(bm, getMeasuredWidth(), getMeasuredHeight(), false);}@Overridepublic boolean onTouchEvent(MotionEvent event){final int x = (int) event.getX();final int y = (int) event.getY();if (event.getAction() == MotionEvent.ACTION_DOWN){//填色fillColorToSameArea(x, y);}return super.onTouchEvent(event);}/*** 根据x,y获得该点颜色,进行填充 ** @param x* @param y*/private void fillColorToSameArea(int x, int y){Bitmap bm = mBitmap;int pixel = bm.getPixel(x, y);if (pixel == Color.TRANSPARENT || (hasBorderColor && mBorderColor == pixel)){return;}int newColor;if(myColorType)newColor=myColor;elsenewColor = randomColor();int w = bm.getWidth();int h = bm.getHeight();//拿到该bitmap的颜色数组int[] pixels = new int[w * h];bm.getPixels(pixels, 0, w, 0, 0, w, h);//填色fillColor(pixels, w, h, pixel, newColor, x, y);//重新设置bitmapbm.setPixels(pixels, 0, w, 0, 0, w, h);setImageDrawable(new BitmapDrawable(bm));}/*** @param pixels 像素数组* @param w 宽度* @param h 高度* @param pixel 当前点的颜色* @param newColor 填充色* @param i 横坐标* @param j 纵坐标*/private void fillColor(int[] pixels, int w, int h, int pixel, int newColor, int i, int j){//步骤1:将种子点(x, y)入栈;mStacks.push(new Point(i, j));//步骤2:判断栈是否为空,// 如果栈为空则结束算法,否则取出栈顶元素作为当前扫描线的种子点(x, y),// y是当前的扫描线;while (!mStacks.isEmpty()){/*** 步骤3:从种子点(x, y)出发,沿当前扫描线向左、右两个方向填充,* 直到边界。分别标记区段的左、右端点坐标为xLeft和xRight;*/Point seed = mStacks.pop();//L.e("seed = " + seed.x + " , seed = " + seed.y);int count = fillLineLeft(pixels, pixel, w, h, newColor, seed.x, seed.y);int left = seed.x - count + 1;count = fillLineRight(pixels, pixel, w, h, newColor, seed.x + 1, seed.y);int right = seed.x + count;/*** 步骤4:* 分别检查与当前扫描线相邻的y - 1和y + 1两条扫描线在区间[xLeft, xRight]中的像素,* 从xRight开始向xLeft方向搜索,假设扫描的区间为AAABAAC(A为种子点颜色),* 那么将B和C前面的A作为种子点压入栈中,然后返回第(2)步;*///从y-1找种子if (seed.y - 1 >= 0)findSeedInNewLine(pixels, pixel, w, h, seed.y - 1, left, right);//从y+1找种子if (seed.y + 1 < h)findSeedInNewLine(pixels, pixel, w, h, seed.y + 1, left, right);}}/*** 在新行找种子节点** @param pixels* @param pixel* @param w* @param h* @param i* @param left* @param right*/private void findSeedInNewLine(int[] pixels, int pixel, int w, int h, int i, int left, int right){/*** 获得该行的开始索引*/int begin = i * w + left;/*** 获得该行的结束索引*/int end = i * w + right;boolean hasSeed = false;int rx = -1, ry = -1;ry = i;/*** 从end到begin,找到种子节点入栈(AAABAAAB,则B前的A为种子节点)*/while (end >= begin){if (pixels[end] == pixel){if (!hasSeed){rx = end % w;mStacks.push(new Point(rx, ry));hasSeed = true;}} else{hasSeed = false;}end--;}}/*** 往右填色,返回填充的个数** @return*/private int fillLineRight(int[] pixels, int pixel, int w, int h, int newColor, int x, int y){int count = 0;while (x < w){//拿到索引int index = y * w + x;if (needFillPixel(pixels, pixel, index)){pixels[index] = newColor;count++;x++;} else{break;}}return count;}/*** 往左填色,返回填色的数量值** @return*/private int fillLineLeft(int[] pixels, int pixel, int w, int h, int newColor, int x, int y){int count = 0;while (x >= 0){//计算出索引int index = y * w + x;if (needFillPixel(pixels, pixel, index)){pixels[index] = newColor;count++;x--;} else{break;}}return count;}private boolean needFillPixel(int[] pixels, int pixel, int index){if (hasBorderColor){return pixels[index] != mBorderColor;} else{return pixels[index] == pixel;}}/*** 产生随机颜色* @return*/public int randomColor(){Random random = new Random();int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));return color;}
}
<?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:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.weixu.munal.MainActivity"><com.example.weixu.view.MyRadioGroupandroid:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rbRed"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="红色" /><RadioButtonandroid:id="@+id/rbOrange"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="橙色" /><RadioButtonandroid:id="@+id/rbYellow"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="黄色" /><RadioButtonandroid:id="@+id/rbGreen"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="绿色" /><RadioButtonandroid:id="@+id/rbCyan"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="青色" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rbBlue"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="蓝色" /><RadioButtonandroid:id="@+id/rbPurple"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="紫色" /><RadioButtonandroid:id="@+id/rbBrown"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="棕色" /><RadioButtonandroid:id="@+id/rbBlack"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:text="黑色" /><RadioButtonandroid:id="@+id/rbRandom"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="changeColor"android:checked="true"android:text="随机" /></LinearLayout></com.example.weixu.view.MyRadioGroup><com.example.weixu.view.ColourImageViewandroid:id="@+id/civColorIn"android:gravity="center"android:layout_width="match_parent"android:layout_height="wrap_content"app:srcCompat="@drawable/butterfly" /><Buttonandroid:id="@+id/btClean"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="btClick"android:text="清空" />
</LinearLayout>
package com.example.weixu.munal;import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;import com.example.weixu.view.ColourImageView;import java.util.Random;public class MainActivity extends AppCompatActivity {private ColourImageView civColorIn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();civColorIn.setMyColorType(false); //默认为false,只有选择颜色财位true}private void init() {civColorIn= (ColourImageView) findViewById(R.id.civColorIn);}public void changeColor(View view){switch (view.getId()){case R.id.rbRed:setColor(255,255,0,0);break;case R.id.rbOrange:setColor(255,255,125,0);break;case R.id.rbYellow:setColor(255,255,255,0);break;case R.id.rbGreen:setColor(255,0,255,0);break;case R.id.rbCyan:setColor(255,0,255,255);break;case R.id.rbBlue:setColor(255,0,255,255);break;case R.id.rbPurple:setColor(255,255,0,255);break;case R.id.rbBrown:setColor(255,125,100,10);break;case R.id.rbBlack:setColor(255,0,0,0);break;case R.id.rbRandom:civColorIn.setMyColorType(false); //选择随机则传递falsebreak;}}public void btClick(View view){switch (view.getId()){case R.id.btClean:civColorIn.setImageResource(R.drawable.butterfly); //清空break;}}//如果选择了颜色,传递选中的颜色,并设置为truepublic void setColor(int a,int r,int g,int b){civColorIn.setMyColor(Color.argb(a,r,g,b));civColorIn.setMyColorType(true);}}
Android-图片填色相关推荐
- android studio写一个圆填色,数字填色秘密花园
数字填色秘密花园是一款休闲填色类游戏,拥有大量的美图资源,休闲涂色玩法,让你在闲暇时间享受到充满艺术氛围的游戏体验,同时还支持自由创作玩法哦~本次放出数字填色秘密花园安卓版下载,喜欢休闲艺术涂色类游戏 ...
- Android图片压缩(质量压缩和尺寸压缩)
在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手 ...
- android 图片压缩总结1
在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手 ...
- 最详细的Android图片压缩攻略
Mr.Louis的博客地址: https://blog.csdn.net/weixin_44005563 最近在研究图片压缩原理,看了大量资料,从上层尺寸压缩.质量压缩原理到下层的哈夫曼压缩,走成华大 ...
- android图片处理方法(不断收集中)
//压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...
- python画填色图时,如何让分层的填色变为渐变色
python画填色图时,如何让分层的填色变为渐变色 注:自己用来备忘的 以画海洋的地形图为例 数据为一个三位数据,有经度(lon),纬度(lat),高度(z)三个变量. 我们绘制的地形图为了美观,只想 ...
- Android图片海报制作软件开发实践
Android图片海报制作软件开发实践 项目地址:https://github.com/coolstar1204/MakePoster 本博客分以下几个文章,从头记录我学习Material Desig ...
- python气象数据可视化学习记录1——基于ERA5数据画风场和海平面气压填色叠加图
python气象数据可视化学习记录1--基于ERA5数据画风场和海平面气压填色叠加图 1. 写在前面 2. 图片效果 3. 逐步代码解析 3.1导入库 3.2 读取NC格式数据 3.3 对数据进行加工 ...
- Android图片视频拍摄选取及压缩
Android图片视频选取及压缩上传 此博客的主要技术点 需求 开车了 图片选择库 视频压缩 上传 此博客的主要技术点 视频拍摄.视频选取获取视频地址 视频压缩 视频上传 需求 我的项目1.0版本最近 ...
- Android图片压缩(质量压缩和尺寸压缩)Bitmap转成字符串上传
在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手 ...
最新文章
- b是python文件二进制打开_如何在Python中打开和显示原始二进制数据?
- Ubuntu14.04安装apt-get方法Lnmp环境
- linux端口命令是什么意思,cmd和linux的查看端口命令是什么?
- camera驱动框架分析(上)
- Qt工作笔记-SIGNAL之textChanged
- 15款最佳的响应式 Web 设计测试工具
- 【015】基于51单片机的LCD1602流动字符串proteus仿真设计
- F2FS文件系统一 设计背景及框架结构
- 基于Zabbix的校园网核心监控系统设计与实现
- ES6的新特性,前端必看知识点
- i78700k配什么显卡好_最新适合搭配i7-8700的显卡推荐 i7 8700配什么显卡好
- RFID技术对危化品实行安全化
- 爬虫:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position
- icp许可证和edi许可证区别是什么?
- 发生身份验证错误。要求的函数不受支持(远程连接)
- 百度js 检测输入法_百度快照是什么意思,如何删除百度快照
- 论文阅读——A HYBRID TEXT NORMALIZATION SYSTEM USING MULTI-HEAD SELF-ATTENTION FOR MANDARIN
- 压力测试与服务端调优(1)
- 金士顿DT101 G2 旋转盘量产教程 还可刷固件
- 微信小程序(JAVAScript)实现饼图
热门文章
- 搭建JavaWeb开发环境(Eclipse版)
- php程序员述职材料_php程序员述职报告精选
- bestcoder r44 p3 hdu 5270 ZYB loves Xor II
- 未转变者怎么进入服务器,steam未转变者怎么点到服务器怎么进去 | 手游网游页游攻略大全...
- JavaScript 的 深浅 拷贝
- 什么是hidl_protobuf 在通过 hidl 接口传输时,是不是应该用 string 啊
- 怎样申请淘宝u站?怎么能快速申请到淘宝U站?淘宝u站申请方法
- java计算年龄_java实现简单年龄计算器
- 塑料:聚乙烯(PE). 聚氯乙烯(PVC), 聚苯乙烯(PS), 聚丙烯(PP), ABS 树脂
- 参与美国某大学游戏开发俱乐部 Game Jam 记录与分享