目录

  • 【56.Android P 9.0网络权限http】
  • 【57.布局分包】
  • 【58.mHandler在activity警告 --】
  • 【59.shape划线注意事项】
  • 【60.异或加解密】
  • 【61。onPageScrollStateChanged的三个状态】
  • 【62.Android转场动画】
  • 【63.矢量图简介Vector】
  • 【64.权限请求6.0 M 以上动态】
  • 【65.RecyclerView刷新固定控件】--避免图片闪烁
  • 【66.判断主子线程】
  • 【67.重用布局 】
  • 【67.5. Parcelable和Serializable的效率对比】

【56.Android P 9.0网络权限http】

解决方法:共四种
1、 如果一定要使用明文通信的话,则可以打开AndroidManifest.xml 文件,在 application 元素中添加:
android:usesCleartextTraffic=“true”

  1. 为了安全,不建议上面的使用明文的通信方式,不过上面的这种方法可以作为一种临时的通信策略
  2. 如果声明不使用明文通信,则可以在application元素中添加:
    android:usesCleartextTraffic=”false”
    此声明指示该应用不使用明文网络通信,并使 Android Marshmallow 的平台网络堆栈禁止该应用中的明文通信。例如,如果您的应用意外尝试通过 HTTP 明文请求登录用户,该请求将被阻止,该用户的身份和密码信息不会泄露到网络上。

2、 项目改用https请求;
3、 项目的targetSdkVersion改为27以下;
4、 在res的xml目录下,新建一个xml文件(名称自定义,如 network_security_config.xml),内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>     <base-config cleartextTrafficPermitted="true" />
</network-security-config>

在manifest清单文件配置application:

<application
...android:networkSecurityConfig="@xml/network_security_config"
.../>

【57.布局分包】

模块build.gradle下添加代码,然后每个文件夹下需要有layout文件夹

android {。。。sourceSets {main{res.srcDirs=["src/main/res",  //这个意思是全部资源,包括mipmap等,必须"src/main/res/layout","src/main/res/layout/practice4","src/main/res/layout/practice3",]}}
}

【58.mHandler在activity警告 --】

其一:(Activity中)

private final MHandler mHandler = new MHandler(this);private static class MHandler extends Handler {private final WeakReference<MainActivity> mActivity;public MHandler(MainActivity activity) {mActivity = new WeakReference<MainActivity>(activity);}@Overridepublic void handleMessage(Message msg) {MainActivity activity = mActivity.get();if(activity!=null){}}
}不规范的写法:private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {};};
//另外一个办法private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {//但是不能引用外部方法了return false;}});

其二:(自定义View中)

private TimerHandler mHandler;//采用弱引用防止内存泄漏
private static final class TimerHandler extends Handler {private WeakReference<StudyView> mView;private TimerHandler(StudyView clockView) {mView= new WeakReference<>(clockView);}@Overridepublic void handleMessage(Message msg) {StudyView view = mView.get();//isPlaying是StudyView里的变量if (view != null && view.isPlaying) {view.getTime();    //StudyView里的方法view.invalidate();//重新绘制sendEmptyMessageDelayed(1, 1000);//每1000毫秒一请求}}
}
原文链接:https://blog.csdn.net/qq_38363506/article/details/90903240

【其他警告】

@SuppressLint("SimpleDateFormat")
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");  //解决
SimpleDateFormat newSimpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分", Locale.getDefault());
@SuppressWarnings(“rawtypes”)和@SuppressWarnings({ “unchecked”, “rawtypes” })
不规范写法:Class clazz = Class.forName(“android.view.Display”);
正确写法:Class<?> clazz = Class.forName("android.view.Display");

【59.shape划线注意事项】

line划线时注意一下几点:

  • 只能画水平线,画不了竖线;
  • 线的高度是通过stroke的android:width属性设置的;
  • size的android:height属性定义的是整个形状区域的高度;
  • size的height必须大于stroke的width,否则,线无法显示;
  • 线在整个形状区域中是居中显示的;
  • 线左右两边会留有空白间距,线越粗,空白越大;
  • 引用虚线的view需要添加属性android:layerType,值设为"software",否则显示不了虚线。
<shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="line">  <stroke  android:width="1dp"  android:color="#ff0000"/>  <size  android:height="4dp"/>
</shape> <shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="line">  <solid  android:color="#990000ff"/>  <stroke  android:width="1dp"  android:color="#00ff00"  android:dashWidth="4dp"  android:dashGap="4dp"/>
</shape>

【60.异或加解密】

//java.test里测试  加密与解密的代码相同
int pwd = 9;
String normal = "~!@#$%^&*()_+=-0";
//加密
int len = normal.length();
StringBuilder bui=new StringBuilder();for(int i=0;i<len;i++){System.out.println("char:"+normal.charAt(i));int res=normal.charAt(i)^pwd;bui.append((char)res);  //强转为ASCII字符
}
System.out.println("加密后:"+bui.toString());System.out.println("-------下面代码跟上面一样--------------");String cry=bui.toString();//解密
int len = cry.length();
StringBuilder bui=new StringBuilder();for(int i=0;i<len;i++){System.out.println("char:"+cry.charAt(i));int res=cry.charAt(i)^pwd;bui.append((char)res);  //强转为ASCII字符
}
System.out.println("解密后:"+bui.toString());

【61。onPageScrollStateChanged的三个状态】

viewPager.addOnPageChangeListener(new ViewPager.OnPagerChangeListener(){public void onPageScrolled(int position, float offset, int pix){//参数2:偏移量0-1,滑动到一半可以用0.5 标识//参数3:分辨率,比如1080P的,则就是0-1079}public void onPageSelected(int position){//停止滑动后的位置}public void onPageScrollStateChanged(int arg0){参数arg0有三种取值:0:什么都没做1:开始滑动2:滑动结束打印了一下滑动过程的顺序:从滑动开始依次为:argo== (1,2,0)}
});

【62.Android转场动画】

https://www.jianshu.com/p/86ba2e1eb80c

【63.矢量图简介Vector】

1.两种方法来创建:

  • 1)右击drawable–>Drawable resource file–>设置root
    element为vector,这样的矢量图绘制逻辑完全掌握在开发者手里(自己绘制–》看下面的);
  • 2)右击drawable–>Vector
    Asset,选择SVG或者PSD文件直接生成根标签为vector的xml文件,怎样把png转换成SVG(可以用 阿里iconfont 或者
    http://inloop.github.io/svg2android/)。

作者:宛丘之上兮
链接:https://www.jianshu.com/p/0972a0d290e9

  • width和height:当使用这个矢量图的View的宽高是wrap_content 的时候这两个属性才生效;
  • ewportWidth和viewportHeight:决定画布的宽高,是定义的一个虚拟空间,方便编辑pathData属性,如果pathData中的点超出了这个虚拟空间,超出的部分将不会展现给用户;虚拟空间的原点仍然还是在左上角(R点就是原点)。

简单的vector:https://blog.csdn.net/qq_35323561/article/details/80018898

【64.权限请求6.0 M 以上动态】

//1.简单写法
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){//两种方式String[] perms = {"android.permission.RECORD_AUDIO",Manifest.permission.WRITE_EXTERNAL_STORAGE};//因为是在Activity下,所以可以直接调用if(checkSelfPermission(perms[0]) == PackageManager.PERMISSION_DENIED ||checkSelfPermission(perms[1]) == PackageManager.PERMISSION_DENIED){//自己在onRequestPermissonsResult处理requestPermission(perms, 200);//ActivityCompat.requestPermissions(this,perms,200);} else {....}
}//2.分开  [自己去封装工具类]
//应用
if(checkPermission()){//用户拥有权限...
} else {//去请求requestPermission();
}//检查权限
private boolean checkPermission(){int result = ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO);//如果权限授予了if(result == PackageManager.PERMISSION_GRANTED){return true;} else {return false;}
}
//请求权限
private void requestPermission(){//第一次被拒后 或者之前允许又在设置去掉了 走这里,所以仍要请求权限(但是可以弹窗说名原因)if(ActivityCompat.shouldShowRequestPermissionRationale(this,perms[0])){toast("请在设置里允许权限");//我强制在弹窗请求ActivityCompat.requestPermission(this,new String[]{perms[0],perms[1]}, 1);} else {//请求权限(两种情况)//第一种:第一次请求权限ActivityCompat.requestPermission(this,new String[]{perms[0],perms[1]}, 1);//第二种:拒绝并选择“Never ask again”}
}
//接受权限结果
@override
public void onRequestPermissonsResult(...){if(requestCode == 1){if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){//申请成功。。。逻辑代码} else {//用户拒绝}return;}super.onRequestPermissonsResult(...);
}

shouldShowRequestPermissionRationable 方法会返回以下两种情况:

  • 返回true:
    用户之前在申请权限操作时,点击了“拒绝”按钮,但是没有选中“Never ask again”选项。
    处理方法—— 再次调用requestPermission方法申请权限。
  • 返回false:
    • 用户从来没有申请过此权限;
      处理方法—— 直接调用 requestPermission方法申请权限。
    • 用户之前选中拒绝,并勾选了“Never ask again”选项。
      处理方法—— 弹出自定义对话框,提示用户此操作必须通过权限申请之后才能继续使用此功能,并给用户提供进入权限设置界面的入口。

注意: shouldShowRequestPermissionRationable 返回true的情况
在国内很多手机厂商中设置了自动屏蔽,也就是没有返回true的情况,比如华为、小米等手机。

外例

public void requestPerm(View view){//版本高于23,需要动态申请if(shouldAskPerm){//判断是否已经授予权限if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_CONTACTS)!= PackageManager.PERMISSION_GRANTED){//调用shouldShowRequestPer...判断用户之前的操作if(ActivityCompat.shouldShowRequestPR(this,Manifest.permission.WRITE_CONTACTS)){//用户再对话框中拒绝权限,并没有选中“Never ask again”ActivityCompat.requestPermission(this,new String[]{Manifest.permission.WRITE_CONTACTS},REQUEST_CODE);}else{//第一种:第一次请求权限ActivityCompat.requestPermission(this,new String[]{perms[0],perms[1]}, 1);//第二种:拒绝并选择“Never ask again”//这里需要再SharedPreference里设置第一次申请的操作,默认true,第一次申请后false//跳转到设置里,去手动设置允许}} else{//权限已申请,执行操作。。。}} else{//版本低于高于23}
}
public boolean shouldAskPerm(){return Build.VERSION.SDK_INT>=Build.VERSION_CODES.M;
}checkSelfPermission 检查某权限是否已申请
requestPermissions 主动发送权限申请
shouldShowRequestPermissionRationale 判断用户之前对申请权限做出的动作

【65.RecyclerView刷新固定控件】–避免图片闪烁

https://blog.csdn.net/qq402164452/article/details/53464091

//注意这是三个参数的 onBindViewHolder
@Override
public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {//为空时,就是最初的,初始化if (payloads.isEmpty()) {onBindViewHolder(holder, position);} else {holder.container.setBackgroundColor(position == mCurrentPosition ? ContextCompat.getColor(activity,R.color.color_FF35BAF3) : Color.TRANSPARENT);}
}

【66.判断主子线程】

onCreate->onStart->onPostCreate->onResume->onPostResume
到onPostCreate时,Activity应该已经彻底跑起来了,这时可以测量View宽高

让View重绘, 需要先判断当前线程到底是不是主线程, 然后根据判断结果来决定到底是调用 invalidate() 还是 postInvalidate() 方法. 如果当前是主线程, 就调用 invalidate() 方法; 而如果当前是子线程, 就调用 postInvalidate() 方法, 注意: 子线程中不能调用 invalidate() 方法, 否则就会报异常, 提示我们不能在子线程中更新UI

//1.
public boolean isMainThread() {return Looper.getMainLooper() == Looper.myLooper();
}
//2.
public boolean isMainThread() {return Looper.getMainLooper().getThread() == Thread.currentThread();
}
//3.
public boolean isMainThread() {return Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();
}

Android中切换到主线程更新方法:
?? View.post()方法在android7.0之前,可能会不生效,在异步线程view.post方法不执行的情况居多。建议使用Handler post方法代替。但Android 7.0之后不管在主线程还是在子线程都可以成功执行view.post内部逻辑(https://blog.csdn.net/longlong2015/article/details/88826269)
??在Android 7.0之后的手机上如果通过new创建的View,如果没有将它通过addView()加入到ViewGroup布局中,那通过View.post()发送出去的任务将不再执行,也就无法通过Viwe.post更新UI。

经验证7.0 以后 post可以执行,但是6.0却无法执行
在子线程中更新UI
//1.方法一: view.post(Runnable action)  【注意这个,在下面】textView.post(new Runnable() {@Overridepublic void run() {textView.setText("更新textView");}
});
//view.postDelayed(Runnable action, long delayMillis)用来延迟发送。//2.方法二:runOnUiThread(Runnable action)
注意:context 对象要是 主线程中的MainActivity,这样强转才可以。
runOnUiThread(new Runnable() {@Overridepublic void run() {//此时已在主线程中,更新UI}
});//3.方法三:Handler机制
首先在主线程中定义Handler,Handler mainHandler = new Handler();(必须要在主线程中定义才能操作主线程,
如果想在其他地方定义声明时要这样写
Handler mainHandler = new Handler(Looper.getMainLooper()),来获取主线程的 Looper 和 Queue )
获取到 Handler 后就很简单了,用handler.post(Runnable r)方法把消息处理放在该 handler 依附的消息队列中(也就是主线程消息队列)。(1)假如该方法是在子线程中
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {@Overridepublic void run() {//已在主线程中,更新UI}
});
//Handler还有下面的方法:
//1.postAtTime(Runnable r, long uptimeMillis); //在某一时刻发送消息
//2.postAtDelayed(Runnable r, long delayMillis); //延迟delayMillis毫秒再发送消息(2)假设在主线程中
Handler myHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch(msg.what) {case 0://更新UI等break;default:break;}}
}
之后可以把 mainHandler 当做参数传递在各个类之间,当需要更新UI时,可以调用sendMessage一系列方法来执行handleMessage里的操作。子线程中发送消息到主线程更新UI
/***获取消息,尽量用obtainMessage()方法,查看源码发现,该方法节省内存。*不提倡用Messenger msg=new Messenger()这种方法,每次都去创建一个对象,肯定不节省内存啦!*至于为什么该方法还存在,估计还是有存在的必要吧。(留作以后深入研究)*/
new Thread(new Runnable(){  @Override  public void run() {  //耗时操作,完成之后发送消息给Handler,完成UI更新;  mHandler.sendEmptyMessage(0);  //需要数据传递,用下面方法;  Message msg =new Message();  msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等;  mHandler.sendMessage(msg);  myHandler.sendEmptyMessage(0); //其实内部实现还是和上面一样endEmptyMessageAtTime(int what, long uptimeMillis); //定时发送空消息sendEmptyMessageDelayed(int what, long delayMillis); //延时发送空消息sendMessageAtTime(Message msg, long uptimeMillis); //定时发送消息sendMessageDelayed(Message msg, long delayMillis); //延时发送消息sendMessageAtFrontOfQueue(Message msg); //最先处理消息(慎用)    }               }).start();  //方法四: AsyncTask
/*** 该类中方法的执行顺序依次为:onPreExecute, doInBackground, onPostExecute注意:doInBackground方法是在子线程中,所以,我们在这个方法里面执行耗时操作。同时,由于其返回结果会传递到onPostExecute方法中,而onPostExecute方法工作在UI线程,这样我们就在这个方法里面更新ui,达到了异步更新ui的目的。*/
private class MyAsyncTask extends AsyncTask<String, Integer, String> {/*** 主线程中执行* 在execute()被调用后首先执行* 一般用来在执行后台任务前对UI做一些标记*/@Overrideprotected void onPreExecute() {super.onPreExecute();System.out.println("MyAsyncTask.onPreExecute");}/*** 子线程中执行,执行一些耗时操作,关键方法* 在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。*/@Overrideprotected String doInBackground(String... params) {System.out.println("MyAsyncTask.doInBackground");//只是模拟了耗时操作int count = 0;for (int i = 0; i < 10; i++) {try {count++;publishProgress((count % 100) * 10);Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}// publishProgress((int) ((count / (float) total) * 100));return "耗时操作执行完毕";}/*** 主线程中执行* 在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件中*/@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);progressBar.setProgress(values[0]);textView.setText("loading..." + values[0] + "%");System.out.println("MyAsyncTask.onProgressUpdate");}/*** 在主线程中,当后台操作结束时,此方法将会被调用* 计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。*/@Overrideprotected void onPostExecute(String aVoid) {super.onPostExecute(aVoid);System.out.println("MyAsyncTask.onPostExecute aVoid=" + aVoid);textView.setText(aVoid);}/*** 主线程中执行* 当异步任务取消后的,会回调该函数。在该方法内可以更新UI*/@Overrideprotected void onCancelled() {super.onCancelled();System.out.println("MyAsyncTask.onCancelled");progressBar.setProgress(0);textView.setText("0");}@Overrideprotected void onCancelled(String s) {super.onCancelled(s);}
}

【67.重用布局 】

注意点:
< include>

  • 重写layout_*的属性记得先重写 android:layout_height 和android:layout_width。
  • include如果指定了id,那么layout属性的根视图id会被强制修改成include中的id,如果不注意很容易出现空指针问题。

< merge>

  • 复用在LinearLayout和RelativeLayout中会有不同的表现,在前者会以线性的方式布局,后者delete按钮会遮挡add按钮,所以使用merge标签一定要注意实际的根视图类型
  • merge必须放在布局文件的根节点上
  • merge并不是一个ViewGroup,也不是一个View,它相当于声明了一些视图,等待被添加。
  • 因为merge标签并不是View,所以在通过LayoutInflate.inflate方法渲染的时候, 第二个参数必须指定一个父容器,且第三个参数必须为true,也就是必须为merge下的视图指定一个父亲节点。
  • 因为merge不是View,所以对merge标签设置的所有属性都是无效的
  • 如果Activity的布局文件根节点是FrameLayout,可以替换为merge标签,这样,执行setContentView之后,会减少一层FrameLayout节点。
  • 自定义XXXLayout控件时,如果使用LayoutInflater.inflate(R.layout.xxx, this, true)填充视图,那么该布局的根元素最好设置成,这一点其实是和上一点相同的,有助于直接减少视图层级。

< ViewStub> 懒加载View

你的布局中可能存在很少情况下才用到的复杂布局,比如单条详情、进图条或者是一些撤销消息等等,这些布局可以只在你需要的时候才加载以提升布局的渲染速度。

定义ViewStub
ViewStub 是一个轻量级的视图,它不参与绘制也不参与任何的布局工作。因此,它在视图层级的构建中消耗的资源是非常小的。每一个ViewStub在使用时只需要通过android:layout去定义它需要加载布局文件即可。

下面给出的ViewStub承载了一个透明的进度条,它只在特定情况下才需要展现给用户。

<ViewStubandroid:id="@+id/stub_import"android:inflatedId="@+id/panel_import"android:layout="@layout/progress_overlay"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_gravity="bottom" />

加载ViewStub布局
当我们需要让ViewStub承载的视图展现时,只需要通过调用setVisibility(View.VISIBLE)或者inflate()方法即可

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

一旦ViewStub被可见或者被布局了,那么它就从视图层级中剥离出来,取代ViewStub存在于视图层级的是android:layout属性所指定的布局,该布局的id可以通过android:inflatedId指定。
这里和include一样,android:inflatedId属性也会覆盖layout中根视图的id。

注意点

  • ViewStub只能被inflate一次,多次调用会出异常。第一次setVisibility(View.Visibility)会被动调用一次inflate,因此需要注意。
  • ViewStub被inflate之后会从视图层级中移除,因此再次调用findViewById尝试获取ViewStub对象会返回空,不要尝试使用该对象,否则会出现空指针。
  • ViewStub中layout_*属性都是为新加载的视图的根视图设置的,与 < include > 标签一样,ViewStub加载的根视图自身的layout_*属性会被ViewStub重写。比如layout_height,它不能指定ViewStub本身的高度,因为ViewStub本身的高度和宽度都是0,它指定的其实是需要加载的布局的根视图高度。又由于此,在布局时要注意基于ViewStub的相对布局在ViewStub未inflate之前,位置与实际位置是有偏差的。
  • 一般xml文件中定义的属性都可以通过代码设置,同样ViewStub也可以通过方法setLayoutResource在代码中动态设置应该加载的layout文件,此时一个ViewStub就可以根据逻辑不同使用不同的视图。

【67.5. Parcelable和Serializable的效率对比】

Parcelable和Serializable的效率对比 Parcelable vs Serializable 号称快10倍的效率.

  • 内存序列化上选择Parcelable,
  • 存储到设备或者网络传输上选择Serializable(当然Parcelable也可以但是稍显复杂)
选择序列化方法的原则
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。链接:https://www.jianshu.com/p/df35baa91541

【待测试】

//写在android下面
applicationVariants.all { variant ->variant.outputs.all {outputFileName = "MyAppName${variant.versionName}_${releaseTime()}_${variant.name}.apk"}
}//放到build里面跟apply同级就行了。
static def releaseTime() {SimpleDateFormat str = new SimpleDateFormat("yyyy_MM_dd_KK_mm")return str.format(new Date())
}

Android小提示四相关推荐

  1. Android小提示五

    文章目录 [68.让ProgressDialog在setCancelable(false)时按返回键可dismiss] [69.传递数据 Intent,LiveDataBus,EventBus] [7 ...

  2. Android小提示六

    文章目录 [82.Context启动startActivity注意] [83.Android调用各系统界面] [84.view淡入淡出效果] [85.view绘制监听] [86.Android危险权限 ...

  3. android小项目之新闻客户端四

     基于Android小巫新闻客户端开发---显示新闻详细内容UI设计 2013年2月27日,天气潮湿!!! 距上一次写的主界面业务逻辑实现,已经过来11天,小巫觉得拖得太久了,所以决定尽量把所有的 ...

  4. Android小项目——简易备忘录

    Android小项目--简易备忘录的实现 简易备忘录主要实现功能类似手机默认备忘录,可以对备忘录目录进行增添和删除.在编辑页面,可以显示当前时间,编辑备忘录标题,备忘录内容,设置时间提醒,插入图片等 ...

  5. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0  ...

  6. Android小项目之--前台界面与用户交互的对接 进度条与拖动条(附源码)

    都知道水果公司(苹果)是己尊重用户体验著称的公司,其设计的产品人性化十足,不得不令后来者赞叹,竞相模仿.iphone的成功就是其典型的案例,做为其移动系统的死对头 Google 想要在市场上分得一杯羹 ...

  7. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  8. 四、Android学习第四天——JAVA基础回顾(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天--JAVA基础回顾 这才学习Android的 ...

  9. android自定义吐司通知,IOS 仿Android吐司提示框的实例(分享)

    直接上代码 #import @interface ShowToastView : UIView +(void)showToastView:(UIView *)uiview WithMessage:(N ...

  10. Android----Google code android开源项目(四)

    Google code android开源项目(四) 1.        sparserss http://code.google.com/p/sparserss/ 一个简洁的android rss阅 ...

最新文章

  1. springboot初学
  2. 「AI大咖」ML宗师乔教主,全世界最有影响力的计算机科学家
  3. 上海交大情感脑电数据集(SEED)简介
  4. 从无到有算法养成篇-单向循环链表的常规操作
  5. Python3算术运算符
  6. 重磅亮相KubeCon China,腾讯云为你揭秘国内云商最大容器集群
  7. java gson序列化_java – Gson多态序列化
  8. 【数码管识别】4识别成5或7的问题
  9. php 查找php配置文件php.ini所在路径的二种方法
  10. php和mysql web开发 5_WEB开发圣经:PHP和MySQL Web开发(原书第5版) 原版pdf+完整源码...
  11. 服务器草稿位置在c盘可以吗,T+增加凭证的时候保存草稿,保存到那里去了
  12. 华为路由设置虚拟服务器命令,华为路由器配置ip命令
  13. 三进制计算机_“九章”量子计算机这么猛,到底能做啥?只为了一条公式的结果吗...
  14. 计算机软件维护基本知识,电脑硬件基础维护常识大全
  15. 程序人生 - 如何绘制二维码?
  16. IntelliJ IDEA中项目的包和目录结构显示设置
  17. 微信小程序加水印(含代码效果图)
  18. 后端开发面试自我介绍_一定是最适合你的后端面试指南
  19. Java 动态生成推广海报,带用户头像、昵称、二维码
  20. CMake教程之构建Qt平台

热门文章

  1. 功率放大器ADS仿真实例
  2. 微软的补丁服务器,Microsoft 安全公告 MS17-010 - 严重
  3. 在计算机内部.机器码的形式,在计算机内部,机器码的形式是____。
  4. java 车牌号判断
  5. Android自定义选座,Android实现电影院选座效果
  6. 解决vscode中文乱码的问题
  7. matlab怎么画地震反应谱,地震工程学-反应谱和地震时程波的相互转化matlab编程...
  8. 系统架构设计师论文范文
  9. 前端 js 基于react ts的excel文件模板下载 文件导入、导出
  10. Android 使用反射调用StorageManager中 Hide方法getVolumeList、getVolumeState