1.使用 Integer.parseInt(string)将字符串转成int类型时的时候里面的字符串要去空格,只能去首尾的空格,否则会报java.lang.NumberFormatException。

2.valueof也可以把字符串转成int类型

3.try-catch是最好的解决bug的方式,与其等观察后台可能出现的数据错误不如先为可能的错误做好准备,数据可能不对,但是app不能崩溃。

4.少用对话框,对话框貌似无论如何都无法完全全屏,哪怕测量屏幕的高度赋给它。

5.将进度条放进对话框内以达到黑色覆盖的效果不是很好,因为对话框会与屏幕上部分有间隙。设置一个view覆盖全屏颜色为灰色再放置一个进度条是比较好的方法,若出现覆盖层不能拦截点击事件(覆盖层背后的控件响应点击事件了),可以设置覆盖层的clickable熟悉为true,fragment覆盖activity时点击事件错乱也可以这样做。

5.手动解析json时用opt比用get解析好,因为opt哪怕出错不会导致app崩溃。

6.当使用字节流读取文本时出现部分文字乱码,可以换成字符流readline。

7.若需要获取时间,尽量获取本地时间,system.getcurrenttimemillis(),因为网络时间不一定获取成功,也不一定获取的总是正确的,下面的代码可以获取网络时间。

new Thread(new Runnable() {@Overridepublic void run() {URL urlTime = null;//取得资源对象try {urlTime = new URL("http://www.baidu.com");} catch (MalformedURLException e) {e.printStackTrace();}URLConnection uc = null;//生成连接对象try {uc = urlTime.openConnection();} catch (IOException e) {e.printStackTrace();}try {uc.connect(); //发出连接} catch (IOException e) {e.printStackTrace();}//取得网站日期时间ld = uc.getDate();
//                 转换为标准时间对象date = new Date(ld);}}).start();return date ;

8.webview各种回调方法执行时机和顺序绝不是你想的那样。
9.开发时任何从接口或网络返回的数据都要考虑是否为空,是否正确,是否不存在。
10.偶尔listview设置footview会与最后一个item间隔一个item距离,我也不知道为什么如下图所示最后一个”退出登录“就是footview。

11.如果listview或recycleview之类的控件中某些数据需要隐藏在一开始就不放进去是最好的选择, listview的convertView.setVisibility(View.INVISIBLE)会让item内容不显示但是仍有一个空位,若listview的 android:divider="@null",android:dividerHeight="1dp"则会发现形成了类似于分组的效果,像上面那张图片最上面的空行其实另一种item但是
不显示内容。若listview的convertview设置为gone则会彻底移除不占位置。gridview 无论将convertview设置为GONE或INVISIBLE都不会完全移除,都会留下一个空位,后面的item不会自己补上,有人说将item隐藏时同时将item的宽和高设置为0我没试过不知道会不会影响点击事件和复用。
12.隐藏掉listview或gridview的分割线然后给item和背景设置不同的颜色来形成分割线的效果要好得多。
13.貌似在sdk的一定版本以上时拨打用户的电话需要在代码里确认权限(即使清单文件里已经有权限了),代码如下:
 public boolean check() {PackageManager pm = getPackageManager();boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.CALL_PHONE", "com.objectretail.bcc"));return permission;}
if(permission)为true则startActivity(intent)拨打电话,如果不判断编译会不通过。

14.webview使用时注意以下代码:       
 WebSettings settings = webView.getSettings();settings.setJavaScriptEnabled(true);/*************************************/  /settings.setDomStorageEnabled(true);  //settings.setGeolocationEnabled(true); //这2行代码表示开启webview的localstorage,不过貌似要加上SD卡读取权限,我也不知道localstorage是什么//**************************************/settings.setDefaultTextEncodingName("UTF-8");
15.webview的setchromeclient和setwebviewclient可以同时使用且两者回调方法不同可以实现不同的功能。

16.webview上传图片的事真烦,后面博客再写吧。

17.listview和gridview相互嵌套或在scrollview中的新的写法,重写onMeasure()方法:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}
18.下拉框的效果尽量别用下拉框来实现了,太丑了。
19.picasso和fresco的默认加载错误图片会在加载的url为空或不正确时出现,最重要的事情是app不会崩溃。
20.直接用多种布局的listview即可实现类似于微信分组显示的效果。
21.当textview中的文本因为背景图片的颜色改变而变得不那么显眼时,可以考虑将textview放入线性等其他布局中,给该布局设置一个任意背景色,再将textview的文本设置为与背景色反差较大的颜色就可以了。

22.判断listview的数据是否多于一屏,用于一些奇葩需求,比如当数据不足一屏时隐藏scrollbar,超过一屏时始终显示,代码如下(这段代码网上找到因为最后没用上这个需求):

scrollbar,listView.setOnScrollListener(new OnScrollListener() {  @Override  public void onScrollStateChanged(AbsListView view, int scrollState) {  // TODO Auto-generated method stub  }  @Override  public void onScroll(AbsListView view, int firstVisibleItem,  int visibleItemCount, int totalItemCount) {  // TODO Auto-generated method stub  //有更多  if(totalItemCount > visibleItemCount){  //不满一屏  }else{  }  }  })  

23.让listview的scrollbar始终显示(即不触摸屏幕也显示)可这样设置:

        android:fadeScrollbars="false"android:scrollbarFadeDuration="0"

24.让listview的scrollbar不显示布局里这样写:android:scrollbars="none" ,代码里可以这样写:

View.setVericalScrollbarEnabled(boolean) //false隐藏竖直的进度条
View.setHorizontalScrollBarEnabled(boolean)//false隐藏横着的进度条

25.应用的版本号可以在gradle文件或者清单文件配置,但是某些集成的第三方sdk只能读取清单文件的比如坑爹的百度自动更新。versionCode是给设备程序识别版本(升级)用的,必须是一个interger值,整数,代表app更新过多少次,versionName是给用户看的,可以写1.1 , 1.2等等版本,通常上传到应用市场的app版本号只能越来越高,同一个市场可以传同版本或高版本不能传低版本。

26.关于清单文件中的信息获取包括版本号思路如下(网上找到):在Android中,应用程序的版本号是在AndroidManifest.xml文件中进行配置的,而PackageInfo类则封装了从该配置文件中获取的所有信息,描述了包内容的整体信息,因此,可以使用PackageInfo对象的versionName属性获取应用的版本号。
要怎么获取PackageInfo对象呢?可以通过PackageManager对象来获取。PackageManager是一个检索当前已安装在设备上的相关应用程序包的各种信息的类。PackageManager对象中的getPackageInfo方法可以获取PackageInfo对象,该方法需要传递两个参数:应用包名和条件。通常情况下,应用程序的包名可以通过Activity或Context(Activity继承自Context)的getPackageName()方法获取,而添加可以有很多设置,通常设置为0。
最后是PackageManager对象的获取,Context对象提供了getPackageManager()方法来获取该对象。代码如下:

   PackageManager manager = context.getPackageManager();PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);String version = info.versionName;

27.Imageview的scaletype中的fitxy可以让图片自由伸展铺满整个imageview,显示验证码图片时必用。

28.使用webview加载页面失败时重写onReceivedError()方法可以修改失败的页面(加载另一个html,或让一个全屏的不透明页面覆盖整个webview),以及点击重新加载的逻辑,重新加载后(可能)会回调onPageFinished()方法,此时让该方法中的super.onPageFinished(view, url)最先执行,再执行隐藏自定义失败界面和进度条的代码可以避免因为隐藏过快导致又显示加载失败的系统默认页面。

29.使用viewpage时,viewPager.setOffscreenPageLimit(N);// 设置缓存页面,当前页面的相邻N各页面都会被缓存,之前以为设置为2就是左右各一页,其实是左右各两页。

30.onActivityResult的方法执行是在使用了startactivityforresult()跳转结束回到初始activity时才会回调,以别的方式进入要跳转的activity再回到初始activity时不会回调。

31. onActivityResult()方法被回调还有一个前提是之前的activity必须要用activity.this.finish()这个方法结束,之前没注意这个问题,一直只知道按后退键也会回调,其实是按后退键会在ondestroy()方法里调用finish()方法。setResult()是用来设置回调时要传递的参数的,要在finish()之前调用但使用时机还是比较麻烦。

32.关于setResult()的使用和当设置activity的启动模式为singletask时无法回调onActivityResult()的问题(我自己的项目中activity也是设置成singletask但是一直都可以回调,我也不知道这是为什么),看下面2个链接: onActivityResult()setResult()的调用时机:http://blog.csdn.net/liu_qiqi/article/details/38304033;singleInstance或singleTask的设置导致onActivityResult回调失效:http://blog.csdn.net/u013499299/article/details/50424032。

33.关于静态注册的广播和不绑定的service,他们一直运行在后台,即使在app已经关闭且进程被回收后还能保持运行(需要指定广播和服务运行在新的进程:android:process=“:xxxx”,要加冒号),如果app在运行时,这两者都能访问app中写的类,对象和方法,也能访问各种资源目录下的资源,但是当app被关闭,关于app所有的资源都被回收时,广播和服务应该就不能访问这些资源和方法了,这时候会发生什么我也不知道,我的做法是尽量避免在广播和服务里访问app的需要被动态分配的资源,只访问存储在本地的文件,保持低耦合。关于这一点我也不确定这么做对不对。

34.application的代码到底会被执行几次?app第一次运行时才会执行,还是每一次系统创建app的进程时才会被执行?

35.AlarmManager是闹钟服务,可以设定定时执行,是一个系统级的服务,运行一次就会一直存在(也会被系统回收);其写法和NotificationManager极其类似,可以设置定时启动服务或发送广播。

36.pendingIntent相当于是Intent的封装。通过pendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)系列方法从系统取得一个用于启动一个Activity的PendingIntent对象,可以通过pendingIntent.getService(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于启动一个Service的PendingIntent对象可以通过pendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于向BroadcastReceiver的发送广播的PendingIntent对象.

37. Intent和PendingIntent的区别
a. Intent是立即使用的,而PendingIntent可以等到事件发生后触发,PendingIntent可以cancel
b. Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效
c. PendingIntent自带Context,而Intent需要在某个Context内运行
d. Intent在原task中运行,PendingIntent在新的task中运行

38.静态注册的Brodcastreceiver和非绑定的service中的context可能要context.getApplicationContext才有用。

39.MD5可以用来比较两个字符串是否一样,字符串也可以直接用equals()来比较,下面贴一个生成字符串的MD5码的方法(网上找的):

    public static String md5(String string) {byte[] hash;try {hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("Huh, MD5 should be supported?", e);} catch (UnsupportedEncodingException e) {throw new RuntimeException("Huh, UTF-8 should be supported?", e);}StringBuilder hex = new StringBuilder(hash.length * 2);for (byte b : hash) {if ((b & 0xFF) < 0x10) hex.append("0");hex.append(Integer.toHexString(b & 0xFF));}return hex.toString();}

40.当使用广播接收者时,尽量给接收者设置一个action,可以在清单文件里直接设置<intent-filter>或者代码里new IntentFilter(),在registerReceiver()时设置给广播接收者,原因        是某些手机不设置广播的action,广播接收者不一定能收到广播。

41.在通知栏点击通知跳转到app时,要先判断app是否已经启动。下面的代码可以判断app是否已经启动:

 public Boolean run() {/*** android5.0之后不能通过getrunningtask获得正在运行的任务*/if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {return getActivePackages();} else {return getActivePackagesCompat();}}/*** android5.0+之后判断app是否还在运行** @return*/private Boolean getActivePackages() {List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo info : runningAppProcesses) {if (info.processName.equals(packagename)) {return true;}}return false;}/*** android5.0之前判断app是否还在运行** @return*/private Boolean getActivePackagesCompat() {List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(100);for (ActivityManager.RunningTaskInfo info : runningTasks) {if (info.topActivity.getPackageName().equals(packagename) && info.baseActivity.getPackageName().equals(packagename)) {return true;}}return false;}

如果app已经启动了,可以用以下代码跳转的指定的activity:

 Intent intent1 = new Intent(context.getApplicationContext(), MainActivity.class);intent1.addCategory(Intent.CATEGORY_LAUNCHER);intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent1);

这里的给intent设置的addCategory()有如下解释:

大部分手机都ok, 点击通知可以正常启动应用, 但是部分手机就不行了 (如华为P6)
经过一番折腾, 添加了下面一句, 问题就解决了:
resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);原来, 应用的 "入口Activity" 必须要添加Intent.CATEGORY_LAUNCHER(值: Android.intent.category.LAUNCHER)这个Category, 否则应用就无法启动.  当应用被杀死后, 我们点击通知就是要重新启动应用, 重新启动应用就要从"入口Activity"启动,
而我所做的项目中的MainActivity确不是 "入口Activity".  因此无法启动.
因此你要启动应用, 而你启动的Activity有不是"入口Activity"时, 就必须给intent添加 Intent.CATEGORY_LAUNCHER  这个Category.说明: "入口Activity" 就是App的启动入口, 可以想象为main函数, 一般命名为MainActivity, 它再manifest文件中的配置一般有这样一个<intent-filter>
<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

(最后附上这段解释的原地址: 点击打开链接)

如果app没有启动,可以使用以下代码正常启动app:

Intent launchIntentForPackage = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packagename);launchIntentForPackage.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);context.startActivity(launchIntentForPackage);

42.如果要从外部打开app,比如通知栏、广播等,必须设置addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),所以也必须设置activity的启动方式为singletask,否则会导致总是启动新的app而不是回到已经打开的app.

43.清单文件中的activity的exported属性:在Activity中该属性用来标示:当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动。如果被设置为了false,那么这个Activity将只会被当前Application或者拥有同样user ID的Application的组件调用。exported 的默认值根据Activity中是否有intent filter 来定。没有任何的filter意味着这个Activity只有在详细的描述了他的class name后才能被唤醒 .这意味着这个Activity只能在应用内部使用,因为其它application并不知道这个class的存在。所以在这种情况下,它的默认值是false。从另一方面讲,如果Activity里面至少有一个filter的话,意味着这个Activity可以被其它应用从外部唤起,这个时候它的默认值是true。(这一条与41条遥相呼应)。微信的分享回调activity的exported属性设置就是true,这里如果设置为true还会有一些别问题,贴两张图:

44. BroadcastReceiver的onreceive()方法最多执行10秒钟,如果超过10秒会抛出“ANR”,当广播接收者onReceive方法需要执行很长时间时,最好将此耗时工作通过Intent发送给Service,由Service完成,并且不能使用子线程解决,因为BroadcastReceiver是接收到广播后才创建的,并且生命周期很短,因此子线程可能在没有执行完就已经被杀死了.由于只能执行10秒钟的问题所以onreceive()方法中接收到的数据,创建的变量等生命周期都很短,10秒钟后就全部为空了。(做项目时遇到一个brodcastreceiver接受2种广播,接收第一种时读取广播中的数据,解析并加工生成对象放到一个集合中并用一个notificationmanager发送通知,等接收到第二种广播时取出集合中的数据,但是发现接受第二种广播时集合和notificationmanager都为空了).
45.webview可以指定缓存的位置和大小,并且缓存和H5的缓存是分开的。
46.context.getexternalstorage()获得的是默认存储的位置并非一定是系统的sdcard,如果你将外置的sdcard设置为默认存储,则获得的就是这张插入的sdcard。
47.传递序列化的对象时,如果是内部类的对象,则内部和外部都要序列化,且如果传递装着对象的集合时只能传Parcelable的对象集合,不能传Serializable对象的集合。
48.补间动画的repeatMode属性需要和repeatCount属性一起使用才有效。而动画实际的执行次数是在repeatCount的数值上+1,因为即使没有repeatCount属性动画也至少执行一次。

49.在listview中用radiobutton实现单选效果,有很多种方式可以实现,我只用过2种:第一种,在adapter中使用一个整型的currentposition标示被选中项,默认值为0,在getview方法中,判断position是否等于currentposition,如果等于则这个item是被选中项,修改radiobutton的状态即可,radiobutton的点击事件里,将position替换currentposition的值,然后notifydatasetchange()就行了,listview的OnItemClickListener中,获取adapter中的currentposition的值替换为点击项的positon即可。但是这种方法有一些bug,因为偶尔会发生position错乱的问题,也不算错乱吧,就是比如只有4个item,一屏显示3个,第一次加载就加载完了4个,但是快速来回滑动时就发现第一个和第四个居然互相复用,并且加载第一个时getview中打印的position居然是3,加载第四个时getview中打印的position是0,但是加载的文本等数据又是对的,就是radiobutton的状态不对。所以推荐第二种方法,应该也是网上用的最多的方法:直接在item对应的实体类中加入一个ischecked属性来判断是否被选中,第一次显示listview时根据ischecked属性控制radiobutton的状态,在radiobutton的onclicklistener中遍历list集合,先把所有的对象的ischecked属性全部置为false,再根据position把点击的那个radiobutton的item对应对象的ischecked属性置为true,然后notifydatasetchange(),listview的OnItemClickListener中,同样先遍历集合把所有的置为false,接着根据点击的那个position修改对应item对象的ischecked属性。如果需要获得所点击项对象,可以直接遍历list集合,找到ischecked为true的,也可以遍历listview。listview.getchildAt(i).findviewbyid找到radiobutton,判断其状态,为true获取item的position.贴一些之前写的代码:

holder.enterprise_rb.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {for (SellerInfo sellerInfo :list) {sellerInfo.setIschecked(false);}list.get(position).setIschecked(true);notifyDataSetChanged();}});
dialog_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {for (SellerInfo sellerinfo :sellerinfolist) {sellerinfo.setIschecked(false);}sellerinfolist.get(position).setIschecked(true);adapter.notifyDataSetChanged();}});
  choose_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {for (int i = 0; i < sellerinfolist.size(); i++) {if (sellerinfolist.get(i).ischecked()) {SellerInfo sellerInfo = sellerinfolist.get(i);Intent intent = new Intent(Login_Activity.this, MainActivity.class);Bundle bundle = new Bundle();bundle.putSerializable("sellerinfo", sellerInfo);intent.putExtras(bundle);startActivity(intent);Login_Activity.this.finish();}}}});

50.BaseAdapter中有一个可以重写的方法叫isEnable(),这个方法可以用来控制每一个item能否被点击,当返回true时表示整个item可以被点击,当返回false时表示整个item不可被点击。

51.一种新的闪屏页延迟跳转的新思路

        /*** 设置停顿2秒跳转到引导页或者主页面或者登录页*/new Handler() {@Overridepublic void handleMessage(android.os.Message msg) {if (isfirstopen) {startActivity(new Intent(SplashActivity.this, GuideActivity.class));ioqt_sp.edit().putBoolean("isfirstopen", false).commit();} else {if (islogined) {startActivity(new Intent(SplashActivity.this, HomeActivity.class));} else {startActivity(new Intent(SplashActivity.this, LoginActivity.class));}}finish();}}.sendEmptyMessageDelayed(0, 2000);

52.一般用来设置验证码倒计时的方法

    /*** 倒计时开始的方法*/private void startTimer() {if (timeCountDown == null) {timeCountDown = new TimeCountDown(120000, 1000, tv_getctfcode, "重新发送");//第一个参数为millisInFuture,倒计时的总时间,为毫秒。}timeCountDown.start();}

倒计时类

public class TimeCountDown extends CountDownTimer {private TextView view;private String str;/*** @param millisInFuture    The number of millis in the future from the call*                          to {@link #start()} until the countdown is done and {@link #onFinish()}*                          is called.* @param countDownInterval The interval along the way to receive*                          {@link #onTick(long)} callbacks.*/public TimeCountDown(long millisInFuture, long countDownInterval, TextView view, String str) {super(millisInFuture, countDownInterval);this.view = view;this.str = str;}@Overridepublic void onTick(long millisUntilFinished) {view.setClickable(false);view.setText(millisUntilFinished/1000 + "秒");}@Overridepublic void onFinish() {view.setText(str);view.setClickable(true);}
}

53.picasso在加载uri时不会加上 Scheme,所以加载本地图片会失败。以下是网络上的解决方法。

Picasso所有load的重载都会将传入参数转化为Uri 再交给RequestCreator处理而Picasso.load(localImagePath) 转化为Uri是没有 Scheme的 uri: "/storage/emulated/0/Android/data/xxxx/xxx.png"
这样当然无法解析图片了解决方式:
Picasso.load(new File(localImagePath)) 就可以了,File转化为Uri 是包含Scheme的,
uri: "file:///storage/emulated/0/Android/data/xxxxx/xxx.png"

54.okhttp同时上传文件和表单参数

 private void modifyUserMessage() {OkHttpClient okHttpClient = new OkHttpClient();//FORM表单形式上传MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);if (TextUtils.isEmpty(url)) {File file = new File(url);RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);// 参数分别为, 服务端请求key ,文件名称 , RequestBodybuilder.addFormDataPart("image", file.getName(), requestBody);}if (map != null) {// map 里面是请求中所需要的 key 和 valuefor (Map.Entry entry : map.entrySet()) {builder.addFormDataPart(entry.getKey().toString(), entry.getValue().toString());}}Request request = new Request.Builder().url(BaseUrl.BASE_URL + BaseUrl.MODIFYUSERMESSAGE_URL).post(builder.build()).build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {CustomToast.ShowShortToast(Cpt_userinfoActivity.this, e + "");}@Overridepublic void onResponse(Call call, Response response) throws IOException {final String s = response.body().string();CustomToast.ShowShortToast(Cpt_userinfoActivity.this, "" + s);}});}

55.用intent直接传递对象

 Intent intent = new Intent();intent.putExtra("data", data); //这个data对象必须序列化,如果是内部类的对象则内部类和外部类都必须序列化,且若传装着对象的集合则只能parceable
//获取传递过来的对象RegisterUser.DataBean dataBean = (RegisterUser.DataBean) data.getSerializableExtra("data");

56.用bundle传递对象

 Intent intent = new Intent();Bundle bundle = new Bundle();bundle.putSerializable("postsListItem", postsListItem);intent.putExtras(bundle);
//获取传递过来的对象Bundle bundle = data.getExtras();PostsListItem postsListItem = (PostsListItem) bundle.getSerializable("postsListItem");

57.edittext.clearfocus()可以让edittext失去焦点,当edittext失去焦点时,输入法会自动关闭。

58.使用compile 'com.jcodecraeer:xrecyclerview:1.3.2'时要注意各个position。

@Override  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  Log.d("bug", "Adapter   " + holder.getAdapterPosition() + "   Layout   " + holder.getLayoutPosition() + "  position  " + position);  }
//原生的recyclerview
Adapter   0   Layout   0  position  0
Adapter   1   Layout   1  position  1
Adapter   2   Layout   2  position  2
Adapter   3   Layout   3  position  3
//xrecyclerview
Adapter   1   Layout   1  position  0
Adapter   2   Layout   2  position  1
Adapter   3   Layout   3  position  2
Adapter   4   Layout   4  position  3
//xrecyclerview的position是正常的,但是另外2种方式获得position都+1了。

59.recyclerview点击事件具体实现

/*** 2.声明接口变量*/private OnItemClickListener mItemClickListener;/*** 1.定义接口*/public interface OnItemClickListener {public void onItemClickListener(int position);public void onItemLongClickListener(int position);}/*** 3.初始化接口变量** @param mItemClickListener*/public void setmItemClickListener(OnItemClickListener mItemClickListener) {this.mItemClickListener = mItemClickListener;}@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {PostsListItem postsListItem = list.get(position);Picasso.with(context).load(postsListItem.getUserimg()).transform(new CircleTransform()).into(holder.iv_userimg);
//        holder.iv_userimg.setImageResource(postsListItem.getUserimg());holder.tv_username.setText(postsListItem.getUsername());holder.tv_contenttitle.setText(postsListItem.getContenttitle());holder.iv_content.setImageResource(postsListItem.getContentimg());holder.tv_content.setText(postsListItem.getContent());if (mItemClickListener != null) {holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mItemClickListener.onItemClickListener(position);}});holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {mItemClickListener.onItemLongClickListener(position);return true;}});}}
//或者在ViewHolder类里面写if (mItemClickListener != null) {itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mItemClickListener.onItemClickListener(getLayoutPosition());}});itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {mItemClickListener.onItemLongClickListener(getLayoutPosition());CustomToast.ShowShortToast(context, getLayoutPosition() + "");return true;}});}

不建议在bindviewholder里面写的原因是删除item如果使用的是notifydataremove(),则position不会立马改变,后面的item依然是删除之前的position,要等到notifydatasetchange()才会变,但如果在ViewHolder里写的,则获取的其实是getlayoutposition(),原生的recyclerview会立马改变position,而不用等到notifydatasetchange().

60.遍历map集合的两种方式:

//第一种方式Set keys = map.keySet( );if(keys != null)for(String s : keys)

获得一个包含所有key的集合,然后for循环取出所有的key,再从map集合中根据key取出value.

第二种方式for(Map.Entry entry : map.entrySet()) {}

使用此种方法必须指定map集合的key和value的数据类型,entry就是map集合中的一对对键值对,entry.getkey和entry.getvalue可以分别取出key和value。

61.android页面进入edittext自动获取焦点,弹出软键盘解决方法

//在edittext的父布局中加入上面2个属性
android:focusable="true"
android:focusableInTouchMode="true"

62.在LineraLayout中,当设置Android:orientation="horizental" ,子控件的android:layout_gravity="left",android:layout_gravity="right"是无效的,但可以用一下方法达到2个控件分别居左和居右的效果。

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"
/>
</LinearLayout>

设置 android:layout_width="0dp",android:layout_height="wrap_content",android:layout_weight="1"这三个属性后,就会把match_parent剩下的布局给撑满,所以会把右边那个textView挤到最右端。这样就能达到在LinLinearLayout中水平方向上的有两个textview一个居左,一个居右的效果。

63.某些时候自动隐藏导航栏,亮点在于自动改变布局大小,不会覆盖,在OnCreate方法中使用:myview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)其中的myview 可以为Layout中任意的一个View对象(可以由findViewById得到)。此时该Activity显示时会自动隐藏Navigation Bar,但有触摸事件时重新显现Navigation Bar。屏幕的Layout会自动收缩适应新的屏幕大小。

64.另外一种隐藏导航栏的方式:

    /*** 隐藏导航栏** @param activity 当前Activity*/public static void hideNavigationBar(Activity activity) {int uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_FULLSCREEN;if (android.os.Build.VERSION.SDK_INT >= 19) {uiFlags |= 0x00001000;} else {uiFlags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;}activity.getWindow().getDecorView().setSystemUiVisibility(uiFlags);}

这种方式不会挤压布局,而是会让导航栏覆盖在布局上面。并且在Activity中还要重写:

    @Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);if (hasFocus) {SystemUtil.hideNavigationBar(this);}}

不然的话,下拉通知栏或弹出对话框后,导航栏不会隐藏。

android新手开发备忘录相关推荐

  1. android偏移动画,Android新手开发之旅-Android动画之位移动画

    本帖最后由 liu 于 2018-12-27 16:02 编辑 TranslateAnimation位移动画 实现有两种方式: 一.xml+java代码 在res下新建anim文件夹,在res/ani ...

  2. Android新手如何学习开发一款app?

    毫无疑问,开发一款自己的App对于初学者来说,无论从技术学习,还是找工作(或者装x),都是一大利器.那么如何才能快速上手,开发一款属于自己的app.本篇文章仅以自己的一些经验给更多的Android新手 ...

  3. android studio开发个人备忘录算法设计_Android Studio 4.1 发布,全方位提升开发体验...

    作者 / Scott Swarthout, 产品经理我们很高兴发布了 Android Studio 4.1 稳定版,为大家带来一系列针对常见的编辑.调试和优化工作的功能.4.1 版本的重点诉求之一是帮 ...

  4. 5G 时代的 Android App 开发入门与项目实战

    随着移动互联网的持续发展,Android系统从智能手机逐步拓展到平板电脑.智能电视.车载大屏.智能家居.智能手表等诸多设备,Android开发依然是前景可期的IT岗位. 当然,整个社会正在迈向5G时代 ...

  5. 使用IntelliJ IDEA 13搭建Android集成开发环境(图文教程)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  6. 使用Android Studio搭建Android集成开发环境(图文教程)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  7. Tango+Daydream,刀剑合璧的Android VR开发

    Tango+Daydream,刀剑合璧的Android VR开发 2017-01-03 随着ASUS在CES2017上宣布了全球第一款同时具有Tango和Daydream两种能力的ZenFone AR ...

  8. 转:10个常见的 Android 新手误区

    转自:http://www.oschina.net/question/157182_61140 1.不读Android开发文档 Android开发者网站可以很好的帮助你.很多的文档也可以通过SDK工具 ...

  9. ios新手开发——toast提示和旋转图片加载框

    不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图: 有过一点做APP经 ...

最新文章

  1. imitativesimulate
  2. 软件项目管理的75条建议
  3. C/Cpp / const 用法
  4. 10.completion_suggester
  5. FPGA浮点数定点化
  6. 如何删除Apple Music中的连接功能
  7. c语言100位整数变量声明_C ++程序动态声明一个整数变量并打印其内存地址
  8. 表贴电阻尺寸与什么有关_0欧电阻存在的意义?看了就懂了
  9. bboss v5.5.3 发布,Elasticsearch Rest Client
  10. 专业心理性格测试软件,what is my color心理性格测试
  11. ae渲染文件服务器,在 After Effects 中自动执行渲染和网络渲染
  12. 爬虫第四关——寻找周杰伦
  13. 12306 流程解析
  14. NS3学习记录(四)--加入新模型及聚合Aggregate
  15. React中Mpegts播放器的使用
  16. 观点丨DALL-E 2、AI研究的未来以及OpenAI的商业前景
  17. 自学Java!三面蚂蚁核心金融部,Java岗
  18. 图书管理系统 数据库实现(oracle)
  19. unity之Matrix4x4.TRS(Vector3 pos, Quaternion q, Vector3 s)的原理
  20. 写一些生活的琐事(纯属发泄)

热门文章

  1. 如何治理“网络暴力” 在人类文明不断发展向前的进程中,大数据时代应运而来。数学建模解题步骤,愚见而已,欢迎指错和探讨呀~
  2. 青萍之末 光伏“抢屋顶”风潮来袭
  3. Conda base环境被破坏,还原方法,亲测有效
  4. Android 扒开美女衣服
  5. 分治法循环赛c语言,循环赛问题分析和C语言代码-分治法.doc
  6. 【报错】打包不成功没因为TEST文件
  7. LRS2 train.txt、val.txt和test.txt这三个文件是数据集文件列表
  8. collection.stream用法
  9. C语言:学生信息管理系统
  10. Oracle 补充日志分类和相关操作, logminer cdc实时同步数据变化,提取归档日志进行数据挖掘,相关代码实现