目录
1. Java中设置控件的大小需要把dp先转换为像素(转换如下)
2. Java中设置GridLayout布局的layout_columnWeight属性
4. 设置字体颜色为黑色,但显示的是灰色。【使用以下写法设置即可】
5. Java代码中设置TextView的drawable不生效问题
6. 图标使用图片格式模糊,可使用以下方式改善【前提是需要svg源文件】
7. 加了layout_weight="1"的权重,只有一个元素怎么让它只占一半?
8. 为什么GridLayout布局中加了layout_columnWeight="1"还是超出了屏幕大小?
9. 有头像的情况下展示头像,没有头像的情况下展示用户的名字。
12. LinearLayout布局内的组件设置layout_gravity="right"无效
17. NumberPicker设置item的颜色和大小以及分隔线的厚度和颜色
18. 修改TextView和EditText中的hint字体大小
19. 设置BottomSheetDialog向下滑动不关闭弹窗并保留点击背景时才关闭弹窗
20. 原生TabLayout调用getOrCreateBadge报错
22. Android中一个Activity关闭另一个Activity或者在一个Activity中关闭多个Activity
25. BottomSheetDialog内放两个RecyclerView时,一个可以滑动,一个不能滑动
27. 当Activity、Fragment、PopupWindow内的EditText失去焦点后隐藏输入法(软键盘)
28. 不使用字符串拼接或分割的方式如何给url追加参数和获取参数
29. 使用dataBinding在xml中进行判断,隐藏某个控件的条件成立时,控件先出现一会后才隐藏的问题
Android控件/框架开源库收集
- 【开源排行榜】GitHub - getActivity/AndroidGithubBoss: Github Android 国内个人技术排行榜
- 【框架】Android 常用开发框架_汤米粥的博客-CSDN博客_安卓开发框架
- 【框架】Android 主流通用常用框架汇总(持续更新)-云社区-华为云
- 【控件】GitHub - wasabeef/awesome-android-ui: A curated list of awesome Android UI/UX libraries
- 【控件】很值得收藏的安卓开源控件库 - 终端研发部 - 博客园
- 【控件】GitHub上受欢迎的Android UI Library
- 【Android 资源知识大全】GitHub - Arisono/android-bookmark: 【资料汇总】Android 资源知识大全 https://www.yundashi168.com/154.html
- 【开源库】Android 开发常用三方库(2021) - 掘金
配置国内仓库
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin'}
https://maven.aliyun.com/repository/public其实包括了central仓库和jcenter仓库
1. Java中设置控件的大小需要把dp先转换为像素(转换如下)
dp * this.getResources().getDisplayMetrics().density + 0.5
2. Java中设置GridLayout布局的layout_columnWeight属性
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
param.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
param.width = 0;
view.setLayoutParams(param);
3. 设置字体样式为粗体
textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
4. 设置字体颜色为黑色,但显示的是灰色。【使用以下写法设置即可】
textView.setTextColor(getResources().getColor(R.color.black));
5. Java代码中设置TextView的drawable不生效问题
Drawable drawable = getResources().getDrawable(R.drawable.tttt);
// 添加setBounds即可
drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight());
textView.setCompoundDrawables(drawable,null,null,null);
6. 图标使用图片格式模糊,可使用以下方式改善【前提是需要svg源文件】
假如我需要的图标在阿里的iconfont上有,那么可以选择下载svg格式的,如下:
接着需要在Android Studio中自带的工具进行转换,转换操作如下:
转换结果如下:
接着只需要引用对应的文件名即可使用。。。
7. 加了layout_weight="1"的权重,只有一个元素怎么让它只占一半?
在LinearLayout中添加属性android:weightSum="2"即可,如下:
8. 为什么GridLayout布局中加了layout_columnWeight="1"还是超出了屏幕大小?
设置layout_columnWeight="1"的同时也要设置layout_width="0dp",这样即可解决,在线性布局中设置的layout_weight="1"也跟上面一样将宽度值设为0dp即可!
GridLayout布局中有个坑:假设我添加了一个columnCount为2的值,但是这个布局里只有一个控件的话即使设置了layout_columnWeight的值为1,它还是会占一整行!用线性布局的话不会出现这个问题。
9. 有头像的情况下展示头像,没有头像的情况下展示用户的名字。
我的实现方式是通过FrameLayout来实现,至于显示图像还是文字,在代码中进行控制
xml:
<FrameLayout
android:id="@+id/avatar_container"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/circle_background"
android:padding="1dp" />
创建一个名为circle_background.xml的可绘制资源文件,用于绘制圆形背景和边框。在res/drawable目录下创建该文件,并添加以下内容:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景色 -->
<solid android:color="@color/blue_1682C9" />
<!-- 实现描边效果 -->
<stroke
android:width="1dp"
android:color="@android:color/white" />
<!-- 圆角 -->
<corners android:radius="50dp" />
</shape>
代码中控制显示图像还是文字的示例:
FrameLayout avatarContainer = findViewById(R.id.avatarContainer);
// 设置图像
if (hasImage) {
ImageView avatarImageView = new ImageView(this);
avatarImageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
avatarImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
avatarImageView.setImageResource(R.drawable.custom_avatar_image);
// 清除文本
avatarContainer.removeAllViews();
// 添加图像视图
avatarContainer.addView(avatarImageView);
}
// 设置文字
else {
TextView avatarTextView = new TextView(this);
avatarTextView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
avatarTextView.setGravity(Gravity.CLIP_VERTICAL | Gravity.CENTER_HORIZONTAL);
avatarTextView.setText("A");
avatarTextView.setTextColor(getResources().getColor(R.color.white));
// 清除图像
avatarContainer.removeAllViews();
// 添加文本视图
avatarContainer.addView(avatarTextView);
}
10. Toolbar内标题的字体加粗设置
在themes.xml里添加以下样式:
<style name="HeaderToolbarStyle">
<!-- 字体大小 -->
<item name="android:textSize">18sp</item>
<!-- 加粗 -->
<item name="android:textStyle">bold</item>
<!-- 字体颜色 -->
<item name="android:textColor">@color/black</item>
<!--toolbar字体格式-->
<item name="android:typeface">sans</item>
</style>
引用即可,如下图:
11. 使用CardView后有四周出现多出的空白
将cardPreventCornerOverlap属性设为false即可解决
12. LinearLayout布局内的组件设置layout_gravity="right"无效
这是因为LinearLayout默认是水平方向的布局,当水平方向时只有top和bottom有效,垂直方向布局时left和right才有效,所以我们需要给LinearLayout的orientation属性设为vertical即可
13. 在Fragment中处理返回事件,官方例子
public class FormEntryFragment extends Fragment {
@Override
public void onAttach( @NonNull Context context) {
super.onAttach(context);
OnBackPressedCallback callback = new OnBackPressedCallback(
true // default to enabled
) {
@Override
public void handleOnBackPressed() {
// TODO 触发后的逻辑
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(
this, // LifecycleOwner
callback);
}
}
14. ListView布局的一些问题
当我在ListView控件下添加一个Button控件时,Button控件一直溢出屏幕,如下图:
要解决该问题需要为ListView控件添加android:layout_weight="1"的属性,以及把高度设为0dp即可解决,效果如下图:
注意:我的布局是在LinearLayout当中的!!!
15. 去除WebView按钮聚焦时出现的黄框
在页面中添加以下css样式即可解决
.xxx{
outline: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-focus-ring-color: rgba(0, 0, 0, 0);
}
.xxx:active{
outline: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-focus-ring-color: rgba(0, 0, 0, 0);
}
16. 获取显示在当前Activity的Fragment
首先你需要找到当前Activity的布局文件,要知道你的Fragment是放在哪个FrameLayout下的,比如我的Fragment是放在这个FrameLayout下,如图(注意id):
接着只需要在你的Activity加上下面这段代码即可获取:
// 注意你的id是布局文件中FrameLayout标签的id
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.layout);
17. NumberPicker设置item的颜色和大小以及分隔线的厚度和颜色
在themes.xml中添加以下的主题样式:
<!-- 时间选择器分隔线样式主题 -->
<style name="NumberPickerTheme">
<!--字体大小-->
<item name="android:textSize">14sp</item>
<!--字体颜色-->
<item name="android:textColorPrimary">@color/black_333</item>
<!--分隔线颜色-->
<item name="colorControlNormal">#2B000000</item>
</style>
接着在控件当中引用即可:
<!--selectionDividerHeight设置的是分隔线的厚度-->
<NumberPicker
android:layout_width="match_parent"
android:layout_height="match_parent"
android:selectionDividerHeight="1px"
android:theme="@style/NumberPickerTheme" />
18. 修改TextView和EditText中的hint字体大小
使用以下方法即可:
/**
* 设置文本视图提示文本大小
*
* @param textView TextView
* @param hint 提示内容
* @param hintTextSize 提示文字大小
*/
public static void setTextViewHintTextSize(TextView textView, String hint, int hintTextSize) {
SpannableString spannableString = new SpannableString(hint);
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(hintTextSize, true);
spannableString.setSpan(absoluteSizeSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setHint(new SpannableString(spannableString));
}
19. 设置BottomSheetDialog向下滑动不关闭弹窗并保留点击背景时才关闭弹窗
bottomSheetDialog.getBehavior().setHideable(false);
20. 原生TabLayout调用getOrCreateBadge报错
报错信息:
The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).
译文:
此组件的样式要求您的应用主题为 Theme.MaterialComponents(或后代)。
我们只需要给TabLayout组件设置上主题即可,如下图:
android:theme="@style/Theme.MaterialComponents.Light.NoActionBar"
21. 根据重力感应自动横竖屏切换,并且不走生命周期
在AndroidManifest.xml中给需要自动横竖屏切换的activity添加以下配置:
android:configChanges="orientation|keyboardHidden|screenSize"
相关文章:Android横竖屏切换工具 - 掘金
22. Android中一个Activity关闭另一个Activity或者在一个Activity中关闭多个Activity
参考链接:Android中一个Activity关闭另一个Activity或者在一个Activity中关闭多个Activity - 知乎
23. 跑马灯效果实现
<TextView
android:id="@+id/marquee_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="这是一个长文本跑马灯效果的示例,你可以在这里显示你的长文本内容。"
- android:ellipsize="marquee":设置文本超出视图宽度时的处理方式为滚动。
- android:fadingEdge="horizontal":为文本的左右两边添加淡出效果。
- android:marqueeRepeatLimit="marquee_forever":设置跑马灯的滚动次数为无限次。
- android:scrollHorizontally="true":让文本可以水平滚动。
- android:singleLine="true":让所有文本都在一行内显示。
代码中添加:
TextView marqueeText = (TextView) this.findViewById(R.id.marquee_textview);
// 不加这个没有跑马灯效果
marqueeText.setSelected(true);
如果你是在Fragment中使用还需要在onDestroyView中将值设置成false,如果你是在Activity中使用则在onDestroy中设置,否则可能有内存泄露
marqueeText.setSelected(false);
24. TextView内容超过一定字数则显示...
android:maxLines="1"
android:ellipsize="end"
android:maxEms="11"
25. BottomSheetDialog内放两个RecyclerView时,一个可以滑动,一个不能滑动
BottomSheetDialog是可以进行滑动关闭的,而滑动是由BottomSheetBehavior实现的,在BottomSheetBehavior的内部又控制了视图内只允许一个可滑动的控件,所以才会出现这种情况。你可以在不可滑动的RecyclerView控件添加,
android:nestedScrollingEnabled="false"
或者在代码中控制
ViewCompat.setNestedScrollingEnabled(recyclerView1, false)
你会发现这个时候它可以滑动了,但另一个就不能滑动了。网上一堆其他嵌套控件的方式,我用了没效果,改成使用PopupWindow就都正常了
26. 选择照片或拍照上传
跳转拍照的例子:
ActivityResultRegistry registry =
((androidx.activity.ComponentActivity)activity).getActivityResultRegistry();
registry.register("testfile", new ActivityResultContracts.TakePicture(), result -> {
// 如果图像被保存到给定的Uri中,则result返回true
}).launch(uri);
跳转选择照片(单选):
ActivityResultRegistry registry =
((androidx.activity.ComponentActivity)activity).getActivityResultRegistry();
registry.register("testfile", new ActivityResultContracts.GetContent(), result -> {
Log.i("image", result.get(0).getPath());
}).launch("image/*");
跳转选择照片的例子(多选):
ActivityResultRegistry registry =
((androidx.activity.ComponentActivity)activity).getActivityResultRegistry();
registry.register("testfile", new ActivityResultContracts.GetMultipleContents(), result -> {
Log.i("image", result.get(0).getPath());
}).launch("image/*");
选择照片后返回的是Uri,如果你需要将图片上传到服务端,还需要获取到真实的文件才可,下面的方法是一个例子。ActivityResultRegistry除了上面的使用方式外还能够用来申请权限,用处还有很多。
Uri转File:
@RequiresApi(api = Build.VERSION_CODES.Q)
public static File uriToFileApiQ(Context context, Uri uri) {
File file = null;
// android10以上转换
if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
file = new File(uri.getPath());
} else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
// 把文件复制到沙盒目录
ContentResolver contentResolver = context.getContentResolver();
String displayName = System.currentTimeMillis() + Math.round((Math.random() + 1) * 1000) + "."
+ MimeTypeMap.getSingleton().getExtensionFromMimeType(contentResolver.getType(uri));
file = new File(context.getCacheDir().getAbsolutePath(), displayName);
try (InputStream is = contentResolver.openInputStream(uri);
FileOutputStream fos = new FileOutputStream(file)) {
FileUtils.copy(is, fos);
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
如果你需要更丰富的功能,可以看下这个库:https://github.com/LuckSiege/PictureSelector
27. 当Activity、Fragment、PopupWindow内的EditText失去焦点后隐藏输入法(软键盘)
当Fragment所在的Activity已经实现后相应的效果也会在Fragment中展现,因此我们只需要在Activity中实现即可
Activity:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideKeyboard(v, ev)) {
KeyboardUtils.hideSoftInput(this);
}
}
return super.dispatchTouchEvent(ev);
}
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
if ((v instanceof EditText)) {
int[] l = {0, 0};
v.getLocationOnScreen(l);
int left = l[0],
top = l[1],
bottom = top + v.getHeight(),
right = left + v.getWidth();
return !(event.getRawX() > left && event.getRawX() < right
&& event.getRawY() > top && event.getRawY() < bottom);
}
return false;
}
PopupWindow:
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View view = popupWindow.getContentView().findFocus();
if (view instanceof EditText) {
Rect outRect = new Rect();
view.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
view.clearFocus();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
return false;
}
});
28. 不使用字符串拼接或分割的方式如何给url追加参数和获取参数
追加参数:
// 构建一条链接
Uri uri = new Uri.Builder()
.scheme("http")
.authority("domain.com")
.path("uri")
.appendQueryParameter("param1", "参数1")
.appendQueryParameter("param2", "参数2")
.build();
// 在现有的连接上追加参数
String url = new Uri.Builder()
.path("http://domain.com/uri")
.appendQueryParameter("param1", "参数1")
.appendQueryParameter("param2", "参数2")
.build().toString();
获取参数:
// 第一种
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(url);
String param1 = sanitizer.getValue("param1");
// 第二种
String param2 = Uri.parse(url).getQueryParameter("param2");
29. 使用dataBinding在xml中进行判断,隐藏某个控件的条件成立时,控件先出现一会后才隐藏的问题
比如以下控件:
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="加载错误,点击刷新"
android:visibility="@{loadResult == LoadResult.error? View.VISIBLE:View.GONE}" />
首次刷新的时候这个控件是满足隐藏的条件的,但是该控件在出现一会后才隐藏。出现这个问题的原因是虽然已经给loadResult变量绑定了数据,但却还没立即执行,而是挂起等待了。我们可以手动调用下立即执行的方法即可解决这个问题。
binding.executePendingBindings();
要在绑定数据后调用才有效果。
👍点赞,你的认可是我创作的动力 !
🌟收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!