转载请注意:http://blog.youkuaiyun.com/wjzj000/article/details/50937031
本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp (Retrofit+RxJava+MVP)
第一次尝试在优快云记录自己的成长。(持续不断更新中...)
没有系统的教程与总结,就随意记点自己学习、开发过程中遇到的一些问题。
- (1):ViewPager.setOnPagerChangeListener过时,被addOnPagerChangeListener取代。
- (2):ViewPager中如果new一个自定义的PagerAdapter,那么,new出来的Fragment页面,通过startActivityForResult开启的Activity。setResult后并不会触发new出来的Fragment的onActivityResult回调。
解决方案:new FragmentPagerAdapter。即不自定义PagerAdapter。
- (3):在对View空间进行setColorXXXX等等操作,会方法遇到过时的情况。通过ContexCompat.getXXXX可以通用的解决这个问题。
- (4):ListView的优化(以及RecyclerView):
首先定义ViewHolder,在getView中声明。
先对convertView进行判空,convertView==null。然后new ViewHolder,对convertView进行初始化....然后通过convertView.setTag(viewHolder)进行设置Tag。在判空的{}外边,获取viewHolder,进行数据填充。
优化原理避免每次重新findViewById。
当然RecyclerView实现ListView功能时,已经将ViewHolder集成进去,必须复写。简单梳理一个RecyclerView的Adapter的使用过程:
首先声明一个内部类,继承Recycler.ViewHolder,重写构造方法,通过参数itemView初始化RecyclerView所要使用的Item的控件:
public class ViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.tv_title) TextView tvTitle;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
/**
* 当然这里边使用了ButterKnife
* 正常的话我们通过itemView.findViewById即可
*/
}
}
然后让这个Adapter类继承extendsRecyclerView.Adapter<你的Adapter全程.ViewHolder>因为是内部类,所以泛型参数要辣么写紧接着就是重写系统让必须写的是三个方法:
- onCreateViewHolder 此方法返回你的ViewHolder即可
- onBindViewHolder 控件赋值,更新Item的UI
- getItemCount 返回Datas的size即可
在给RecyclerView设置Adapter之前,要setLayoutManager(new LinearLayoutManager(context))
可以非常方便的做成水平,竖直,瀑布流,网格等等的效果。
- (5)drawable下的<shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--填充颜色-->
<solid android:color="#A3A3A3" />
<!--弧形半径-->
<corners android:radius="20dp" />
<!--边框-->
<stroke android:width="4px" android:color="#A3A3A3" />
<!--渐变色 startColor起始颜色,endColor结束颜色,angle表示方向角度。
当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上。-->
<gradient android:startColor="#FFF" android:endColor="#000" android:angle="45"/>
</shape>
- (6)drawable下的<selector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 非触摸模式下获得焦点并单击时的背景图片 -->
<item android:state_focused="true" android:state_pressed="true"
android:drawable= "@drawable/btn_3" />
<!-- 触摸模式下单击时的背景图片-->
<item android:state_focused="false" android:state_pressed="true"
android:drawable="@drawable/btn_4" />
<!--选中时的图片背景-->
<item android:state_selected="true" android:drawable="@drawable/btn_5"/>
<!--获得焦点时的图片背景-->
<item android:state_pressed="true" android:drawable="@drawable/btn_6"/>
<!-- 默认时的背景图片-->
<item android:drawable="@drawable/btn_1" />
</selector>
经过测试,默认时的这个<item>应该放在最后,不然会没有任何效果。
- (7)监听返回键,简单的实现双击退出效果
long exitTime = 0;
@Override
public void onBackPressed() {
if((System.currentTimeMillis()- exitTime)>2000){
Toast.makeText(MainActivity.this, "再点一次,退出", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
}else{
super.onBackPressed();
}
}
- (8)AppComatEditText的使用
想实现输入框水印上移的效果,用在AppComatEditText外套上TextInputLayout控件。属性没啥特别的地方。
但是这里记录一个问题,那就是这个属性android:textColorHint="@color/black"
这样设置再EditText里会改变hint(水印)的颜色,但是在AppComatEditText里没有效果。
想要有效果,要这么使用。
在styles里中的theme里添加:<item name="android:textColorHint">@color/black</item>
这样就可以生效了,其次还有更多的效果,如下:
<!-- AppCompatEditText默认状态状态设置底线颜色 -->
<item name="colorControlNormal">@color/black</item>
<!-- AppCompatEditText选择的底线颜色 -->
<item name="colorControlActivated">@color/black</item>
- (9)获取宽高的方法
首先现在通过wm.getDefaultDisplay().getWidth()这个方法获得屏幕的宽高已经过时。
现在使用的方法是:
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
width = displayMetrics.widthPixels;
height = displayMetrics.heightPixels;
有个更方便的写法:
getResources().getDisplayMetrics().widthPixels
- (10)onCreate()中获取控件长宽,亲测可用:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); btn_ok.measure(w, h); int height = btn_ok.getMeasuredHeight(); int width = btn_ok.getMeasuredWidth();
- (11)今天遇到一个错误FragmentManager is already executing transactions。
解决方式用getChildFragmentManager()替换其他获取FragmentManager方法。这个方法在Fragment类中。
- (12)一个文本的特殊用法:
首先在value下的strings中声明:
<string name="messageGood">%d个赞</string>
然后在java代码中这么写:
setText(String.format(context.getResources().
getString(R.string.messagePeople),相关替换的内容));
其实就是用的java中的String.format。当然%d表示允许替换为整形,那么%s显然就是说允许替换为String字符串啦。
- (13)通过xml写渐变的圆形加载条,效果如下:
代码如下:
drawable/
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%" android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360">
<shape
android:shape="ring"
android:innerRadiusRatio="3"
android:thicknessRatio="8"
android:useLevel="false">
<gradient
android:type="sweep"
android:useLevel="false"
android:startColor="#6BD3FF"
android:centerColor="#FF7121"
android:centerY="0.50"
android:endColor="#FFFF00" />
</shape>
</animated-rotate>
- (14)关于输入法遮蔽EditText的情况处理:
这种情况比较多见,也比较容易解决。今天在此记录一个特殊的情况,就是使用透明状态栏之后,如果解决这类的遮挡问题。
首先依然还是在AndroidManifest中EditText所属的Activity中声明如下代码:
android:windowSoftInputMode="adjustResize|stateHidden"
adjustResize是重新计算页面高度,然后绘制,而不是整体页面上移。正常Activity到此就算完毕了。但是如果是用了透明状态栏
恐怕就要失望了,所以,
最后在对应的布局文件的根标签下,加上这句话:
android:fitsSystemWindows="true"
这样就可以愉快的继续玩耍了。
- (15)text显示无论怎样显示都是全部大写字母,比如Button中:
其实这个问题比较好解决,在xml中的那个控件之中加上这句话android:textAllCaps="false"即可。
当然在java代码也可以设置:
ok,就是这样。new Button(this).setAllCaps(false);
- (16)打开图库:
public void openImage(View view){ Intent openImage=new Intent(Intent.ACTION_PICK,null); openImage.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*"); startActivityForResult(openImage, 6566); } Bitmap bmp; String imagePath; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode== Activity.RESULT_OK&&requestCode==6566){ if (data!=null){ Uri selectImageUri=data.getData(); imagePath = FileUtils.getPathUrlFromUri(this,selectImageUri); bmp= FileUtils.getBitmap(imagePath); imageView.setImageBitmap(bmp); } } }
public static String getPathUrlFromUri(Context context, android.net.Uri uri){ if ( null == uri ) return null; final String scheme = uri.getScheme(); String data = null; if ( scheme == null ) data = uri.getPath(); else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) { data = uri.getPath(); } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) { Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null ); if ( null != cursor ) { if ( cursor.moveToFirst() ) { int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA ); if ( index > -1 ) { data = cursor.getString( index ); } } cursor.close(); } } return data; }
public static Bitmap getBitmap(String path) { Bitmap bm = null; InputStream is = null; try { File outFilePath = new File(path); //判断如果当前的文件不存在时,创建该文件一般不会不存在 if (!outFilePath.exists()) { boolean flag = false; try { flag = outFilePath.createNewFile(); } catch (IOException e) { e.printStackTrace(); } System.out.println("---创建文件结果----" + flag); } is = new FileInputStream(outFilePath); bm = BitmapFactory.decodeStream(is); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return bm; }
- (17)透明度对应十六进制:
00%=FF(不透明) 5%=F2 10%=E5 15%=D8 20%=CC 25%=BF 30%=B2 35%=A5 40%=99 45%=8c 50%=7F
55%=72 60%=66 65%=59 70%=4c 75%=3F 80%=33 85%=21 90%=19 95%=0c 100%=00(全透明)
(18)不root查看数据库:
adb shell
$ run-as 你的包名
$ cp ./databases/你的数据库名 /sdcard/
$ exit
$ exit
adb pull /sdcard/你的数据库名
先记录到此,以后遇到实用的就继续加上。
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp