Android - 简易开发点记录
1.Color用int时 可以使用
Color.parseColor("#FFB452")
2.底部滑动布局自定义,可以使用 (来自于 https://x-sir.blog.csdn.net/article/details/65938389?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control)
PopupWindow
3.手机亮度调整(来自于 https://x-sir.blog.csdn.net/article/details/65938389?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control):
/** * 设置手机屏幕亮度变暗 */ public static void lightoff(Activity activity) { WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); lp.alpha = 0.3f; activity.getWindow().setAttributes(lp); } /** * 设置手机屏幕亮度显示正常 */ public static void lighton(Activity activity) { WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); lp.alpha = 1f; activity.getWindow().setAttributes(lp); }
4.随机生成viewid:
generateViewId()
5.在一个activity中动态生成Fragment:动态生成时,传递一些数据,比如数据显示为什么,控件是否可读,都可以;
public void addOneItem(XXXInfosBean infosBean) { int id = generateViewId(); LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.item_layer, llRoot, false); linearLayout.setId(id); llRoot.addView(linearLayout); PatrolEditInfoItemFragment fragment = new PatrolEditInfoItemFragment(); fragment.isReader = true; fragment.xXXInfosBean = infosBean; FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.add(id, fragment, "FragmentItem" + id); transaction.commit(); } // 删除fragment,当前Fragment上的删除按钮的响应事件,将当前的Fragment传递,remove即可 public void deleteFragment(Fragment fragment) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.remove(fragment); transaction.commit(); }
6.动态生成View
// 将xxx列表 动态添加在UI上 for (int i = 1; i < xxLists.size(); i++) { addXXUI(xxLists.get(i), xxLists.size(), i); } public void addXXUI(String str, int size, int index) { LayoutInflater inflater = LayoutInflater.from(this); // 获取需要被添加控件的布局 // 获取需要添加的布局 R.layout.item_xx是布局文件名称,R.id.xx_item是布局中的根布局 LinearLayout layout = (LinearLayout) inflater.inflate( R.layout.item_xx, null).findViewById(R.id.xx_item); TextView tvXX = layout.findViewById(R.id.tv_xx); tvXX.setText(str); if ((index + 1) == size) { // 最后一个分割线不显示,因为每一个布局底部都有一个分割线,但是最后一个的分割线应该不显示,所以判断一下,如果是最后一个则隐藏 View vXXSplit = layout.findViewById(R.id.v_xx_spilt); vXXSplit.setVisibility(View.GONE); } // 将布局加入到当前布局中(llXXList 是当前activity里的LinearLayout) llXXList.addView(layout); }
7. activity之间intent跳转传参 object
Intent intent = new Intent(XXXActivity.this, XXXXXXActivity.class); // xxxBean 一个对象实例 intent.putExtra("xxxBean", xxxBean); startActivity(intent); // 接收的Activity xxxxxResBean = (XXXBean)getIntent().getSerializableExtra("xxxBean"); /* *对应的Bean里 需要implements Serializable * Bean里的子类里也需要 implements Serializable * 否则会报错java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = xxx.xxx.xxx.XXXXBean) */
8.页面的标题栏,通用,使用一个xml,可以将所有的使用的按钮都放置在这里,默认都隐藏,在对应的页面显示即可
在布局文件中引入<include layout="@layout/common_title" /> <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:id="@+id/rl_title" android:layout_height="wrap_content" android:background="@color/ui_dark_color"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingLeft="@dimen/dp_6"> <RelativeLayout android:id="@+id/rl_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="@dimen/dp_15" android:paddingTop="@dimen/dp_15" android:paddingEnd="@dimen/dp_10"> <ImageView android:layout_width="@dimen/dp_25" android:layout_height="@dimen/dp_25" android:src="@mipmap/back" /> </RelativeLayout> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/dp_15" android:text="@string/title" android:textColor="#ffffffff" android:textSize="@dimen/sp_18" /> </LinearLayout> <RelativeLayout ..../> </RelativeLayout>
9. 限制屏幕截屏
// 限制屏幕截屏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
10. float 保留两位小数
(new DecimalFormat(".00")).format(v)
11. MPChart 自定义 label与value的相对位置(来源于 https://blog.csdn.net/daio_odai/article/details/88570066 做了一点修改)
// 修改源码 PieChartRenderer 类中的 drawValues 方法 // 因为label过长,放在饼图内显示会重叠,故放在饼图外部, // 但是文本过长还是会有重叠的部分 // 所以修改 if (j < data.getEntryCount() && entryLabel != null) { // drawEntryLabel(c, entryLabel, labelPtx, labelPty + lineHeight); /* * 修改 让label 与 value 显示在 一行 * */ // drawEntryLabel(c, entryLabel, labelPtx - 50 , labelPty ); /* * 修改 让label 与 value 显示在 别行 * */ // drawEntryLabel(c, entryLabel, labelPtx, labelPty - lineHeight ); // 获取字符串的长度 x 减去 System.out.println("绘图 饼图 x " + entryLabel + " " + labelPtx + "\n" + " 修改后 " + (labelPtx + (mEntryLabelsPaint.measureText(value +"%") / 2) - (mEntryLabelsPaint.measureText(entryLabel) / 2))); if (!(labelPtxOne > 0)) { labelPtxOne = labelPtx; drawEntryLabel(c, entryLabel, labelPtx + (mEntryLabelsPaint.measureText(value +"%") / 2) - (mEntryLabelsPaint.measureText(entryLabel) / 2), labelPty - lineHeight ); } else if (labelPtx < labelPtxOne / 2){ drawEntryLabel(c, entryLabel, labelPtx + (mEntryLabelsPaint.measureText(value +"%") / 2) + (mEntryLabelsPaint.measureText(entryLabel) / 2), labelPty - lineHeight ); } else { drawEntryLabel(c, entryLabel, labelPtx + (mEntryLabelsPaint.measureText(value +"%") / 2) - (mEntryLabelsPaint.measureText(entryLabel) / 2), labelPty - lineHeight ); } }
12. ImageView 加载网络图片 使用 gilde
//implementation 'com.github.bumptech.glide:glide:4.1.1' RequestOptions options = new RequestOptions(); options.centerCrop() .placeholder(me.iwf.photopicker.R.drawable.__picker_xxx) .error(me.iwf.photopicker.R.drawable.__picker_xx_broken); Glide.with(this) .load(Uri.parse("http://xx/xx/xxxxxx.png")) .apply(options) .thumbnail(0.1f) .into(ivImage);
13. 限制一行显示
// maxLines 限制最大高度,此处无用,随便写的 lines 文本行数 ellipsize省略号显示位置 android:maxLines="5" android:lines="1" android:ellipsize="end"
14.判断某activity是否处于栈顶
/** * * 判断某activity是否处于栈顶 * @return true在栈顶 false不在栈顶 */ public static boolean isTop(Class cls, Context context){ ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); String name = manager.getRunningTasks(1).get(0).topActivity.getClassName(); return name.equals(cls.getName()); } //使用 if (XXXUtils.isTop(XXXXActivity.class,MyApplication.getAppContext())) { ... }
14.监听anrdoid屏幕方向(找了很多,都没有效果,最后找到了一个非常好的 https://blog.csdn.net/h3c4lenovo/article/details/43197759)
// activity 声明 public OrientationEventListener mScreenOrientationEventListener; this.mScreenOrientationEventListener = new OrientationEventListener(this) { @Override public void onOrientationChanged(int i) { // i的范围是0~359 // 屏幕左边在顶部的时候 i = 90; 右旋转 90 // 屏幕顶部在底部的时候 i = 180; 倒置 // 屏幕右边在底部的时候 i = 270; 左旋转 90 // 正常情况默认i = 0; 默认 if(45 <= i && i < 135) { orientationType = 90; } else if(135 <= i && i < 225) { orientationType = 180; } else if(225 <= i && i < 315) { orientationType = 270; } else { orientationType = 0; } } }; mScreenOrientationEventListener.enable(); @Override protected void onPostResume() { super.onPostResume(); if (null == mScreenOrientationEventListener) { mScreenOrientationEventListener.enable(); } } @Override protected void onPause() { super.onPause(); if (null != mScreenOrientationEventListener) { mScreenOrientationEventListener.disable(); } } @Override protected void onDestroy() { super.onDestroy(); if (null != mScreenOrientationEventListener) { mScreenOrientationEventListener.disable(); } ... }
15.通过指定包名和页面,调用第三方APP
// requestCode 11 resultCode 999 数值自定义 private void startThreeActivity() { String packageName = "xxx.xxx.xxx"; String activity = "xxx.xxx.xxx.xxx.XXXActivity"; ComponentName component = new ComponentName(packageName, activity); Intent intent = new Intent(); intent.setComponent(component); intent.putExtra("xxx", "xxxxxx"); startActivityForResult(intent, 11); } // 获取第三方返回的数据 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 11 && resultCode == 999) { String text = data.getStringExtra("xxx"); } } // 第三方APP: 返回数据时,setResult Intent intent = new Intent(); intent.putExtra("xxx", xxxxxxx); setResult(999, intent); finish(); //结束当前的activity的生命周期 // 第三方指定activity 需 android:exported="true" (AndroidManifest.xml)
16.更新UI(有时候更新UI无效,可以使用 runOnUiThread )
runOnUiThread(new Runnable() { @Override public void run() { // 更新UI ... } });
17.数据实时通知更新eventbus
// implementation 'org.greenrobot:eventbus:3.0.0' // 注册 if (!EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().register(this); } @Subscribe(threadMode = ThreadMode.MAIN) public void Event(XXX xxx) { LogUtil.i("aaa", " 测试刷新列表"); ... } // 需要更新数据时调用 EventBus.getDefault().post(new XXX());
18.Activity 穿透多个Activity传值
startActivityForResult(intent, requestCode); //中间使用 setResult(resultCode, intent); // 第一个参数表示结果返回码,一般只要大于1就可以 finish() // 最后根据onActivityResult requestCode resultCode获取 // 或者使用 FLAG_ACTIVITY_FORWARD_RESULT intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); startActivity(intent);
19.motionEvent.getPointerCount()的值一直为1
// 在onTouch监听方法中,ACTION_DOWN需返回true public boolean onTouch(View view, MotionEvent motionEvent) { .... if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){ return true; } return false; }
20.垂直方向上移动View的位置
xxx.setTranslationY(getResources().getDimensionPixelSize(R.dimen.xxx));
21. 含有EditText的activity 进入时会直接弹出软键盘,在EditText的父布局中添加
android:focusable="true" android:focusableInTouchMode="true"
22.国际化时,因为不是全语种翻译导致 values\strings.xml中会有红线警告,虽然不影响运行,但是加上如下 tools:ignore 就可以不警告了
<resources tools:ignore="MissingTranslation" xmlns:tools="http://schemas.android.com/tools">
23. android studio Unable to open debugger port
xxx>adb kill-server xxx>adb start-server
会持续更新,主要是自己看的