原文:https://blog.csdn.net/cc20032706/article/details/51741793Android 开发中，能否设置 DialogFragment 的背景颜色？系统默认的过于深了，非常不友好。解决方案：1.在DialogFragment的onCreateView里面设置，可以将对话框内部的背景设为透明getDialog().getWindow().setBackgroundDrawable(newColorDrawable(Color.TRANSPARENT));2.在DialogFragment的onstart里面设置，可以将对话框外部的背景设为透明@Override public void onStart() { // TODO Auto-generated method stub super.onStart(); Window window = getDialog().getWindow(); WindowManager.LayoutParams windowParams = window.getAttributes(); windowParams.dimAmount = 0.0f; window.setAttributes(windowParams); } ————————————————版权声明：本文为CSDN博主「摄氏三十七度」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/cc20032706/article/details/51741793实测方案1 好用,收藏一下
Android:ClassNotFoundException:Didn't find class "org.apache.http.util.Args"
原文链接：https://blog.csdn.net/qq_33721320/article/details/86620524在 Android 6.0 中，我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始，默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。要继续使用 Apache HTTP 客户端，以 Android 9 及更高版本为目标的应用可以向其 AndroidManifest.xml的###application节点下 添加以下内容：<uses-library android:name="org.apache.http.legacy" android:required="false" />在application下面添加 uses-library。即可 <uses-library android:name="org.apache.http.legacy" android:required="false" /> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.DEFAULT" /> 注：拥有最低 SDK 版本 23 或更低版本的应用需要 android:required="false" 属性，因为在 API 级别低于 24 的设备上，org.apache.http.legacy 库不可用。 （在这些设备上，Apache HTTP 类在 bootclasspath 中提供。）作为使用运行时 Apache 库的替代，应用可以在其 APK 中绑定自己的 org.apache.http 库版本。 如果进行此操作，您必须将该库重新打包（使用一个类似 Jar Jar 的实用程序）以避免运行时中提供的类存在类兼容性问题。
原理见:http://weishu.me/2018/06/07/free-reflection-above-android-p/ 使用方法://https://github.com/tiann/FreeReflection implementation 'me.weishu:free_reflection:1.2.0' 然后在application的 attachBaseContext 方法中初始化 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0 Reflection.unseal(base) } 注:好像有的系统会闪退 --------------------------------------- 可以使用另一个库 //https://github.com/ChickenHook/RestrictionBypass implementation 'com.github.ChickenHook:RestrictionBypass:2.2'
Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题
出处:https://blog.csdn.net/WS1549384743/article/details/51907107Android系统，用户第一次安装应用在系统的安装器安装完成界面有“完成”和“打开”两个按钮。 当用户点击“打开”按钮并进行了一些操作后，若此时用户点击Home键切出应用到桌面， 再从桌面点击应用程序图标试图切回应用接着刚才的操作继续操作时，应用重新到了初始界面， 此时之前从系统的安装完成界面点击打开启动的应用其实还在后面运行。 然而当用户“完全退出”应用，或者在安装完成界面直接点击“完成”按钮再从桌面启动， 或者此应用之前是存在的“覆盖安装”后点击“打开”按钮都是不会导致应用程序“多次启动”的。 从网上查找资料，说设置activity的launchMode等都不能解决此问题。 查看相关博客资料得知原因：利用程序安装器打开程序，启动的Intent是没有带Category， 而我们自己打开程序是带了Category,所以只需要在配置了Intent.ACTION_MAIN的Activity的 onCreate()方法中的添加下面代码即可。放在super.onCreate(savedInstanceState)方法后。 @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); /* broadcastReceiver的注册要在 if (!isTaskRoot()) { Intent intent = getIntent(); String action = intent.getAction(); if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(action)) { finish(); return; } } 之前，否则或出现以下异常 Caused by: java.lang.IllegalArgumentException: Receiver not registered 广播未注册 */ // IntentFilter intentFilter = new IntentFilter(); // intentFilter.addAction(VPN_ONLINE_ACTION); // registerReceiver(broadcastReceiver, intentFilter); if (!isTaskRoot()) { Intent intent = getIntent(); String action = intent.getAction(); if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(action)) { finish(); return; } } }另外，需要注意两点，一是、如果上面的Activity中实现了finish() 和 onDestroy() 方法，一定要保证这两个方法中不会有对空对象的操作以及注销未注册的广播等类似操作，因为第二次打开应用时，程序会调用finish()方法，及触发onDestroy()方法，而这两个函数里面的对象变量都还未进行初始化等操作。二是、finish() 和 onDestroy() 方法中不能有System.exit(0);否则第二次打开应用杀掉进程时也会将第一次打开的应用杀掉。
/** * 检测是否安装支付宝 * * @return */ public boolean checkAliPayInstalled() { Uri uri = Uri.parse("alipays://platformapi/startApp"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); ComponentName componentName = intent.resolveActivity(this.getPackageManager()); return componentName != null; } /** * 检测是否安装微信 * @return */ public boolean checkWechatInstalled() { Uri uri = Uri.parse("weixin://"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); ComponentName componentName = intent.resolveActivity(this.getPackageManager()); return componentName != null; }
出处：https://blog.csdn.net/u011637987/article/details/47723005 在mac下卸载完Android Studio后，重新安装还会引入之前的配置文件。只需把配置文件移除即可。 打开终端，输入命令 rm -Rf ~/Library/Preferences/AndroidStudio* rm ~/Library/Preferences/com.google.android.studio.plist rm -Rf ~/Library/Application\ Support/AndroidStudio* rm -Rf ~/Library/Logs/AndroidStudio* rm -Rf ~/Library/Caches/AndroidStudio*
ScrollView（RecyclerView等）为什么会自动滚动原理分析，还有阻止自动滑动的解决方案
开发中遇到这个问题,在网上找到的比较好的解决方案,复制下来以作记录作者：Wellijohn链接：https://juejin.im/post/5a2a04726fb9a045055e0993来源：掘金著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。引言，有一天我在调试一个界面，xml布局里面包含Scroll View，里面嵌套了recyclerView的时候，界面一进去，就自动滚动到了recyclerView的那部分，百思不得其解，上网查了好多资料，大部分只是提到了解决的办法，但是对于为什么会这样，都没有一个很好的解释，本着对技术的负责的态度，花费了一点时间将前后理顺了下1.首先在包含ScrollView的xml布局中，我们在一加载进来，ScrollView就自动滚动到获取焦点的子view的位置，那我们就需要看下我们activity的onCreate中执行了什么？答：当我们在activity的onCreate方法中调用setContentView(int layRes)的时候，我们会调用LayoutInflater的inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)方法，这里会找到xml的rootView，然后对rootView进行rInflateChildren(parser, temp, attrs, true)加载xml的rootView下面的子View，如果是，其中会调用addView方法，我们看下addView方法：public void addView(View child, int index, LayoutParams params) { ...... requestLayout(); invalidate(true); addViewInner(child, index, params, false); }addView的方法内部是调用了ViewGroup的addViewInner(View child, int index, LayoutParams params,boolean preventRequestLayout)方法：android.view.ViewGroup｛ ...... private void addViewInner(View child, int index, LayoutParams params, boolean preventRequestLayout) { ...... if (child.hasFocus()) { requestChildFocus(child, child.findFocus()); } ...... } } ｝这里我们看到，我们在添加一个hasFocus的子view的时候，是会调用requestChildFocus方法，在这里我们需要明白view的绘制原理，是view树的层级绘制，是绘制树的最顶端，也就是子view，然后父view的机制。明白这个的话，我们再继续看ViewGroup的requestChildFocus方法， @Override public void requestChildFocus(View child, View focused) { if (DBG) { System.out.println(this + " requestChildFocus()"); } if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) { return; } // Unfocus us, if necessary super.unFocus(focused); // We had a previous notion of who had focus. Clear it. if (mFocused != child) { if (mFocused != null) { mFocused.unFocus(focused); } mFocused = child; } if (mParent != null) { mParent.requestChildFocus(this, focused); } }在上面会看到 mParent.requestChildFocus(this, focused);的调用，这是Android中典型的也是24种设计模式的一种（责任链模式），会一直调用，就这样，我们肯定会调用到ScrollView的requestChidlFocus方法，然后Android的ScrollView控件，重写了requestChildFocus方法：@Override public void requestChildFocus(View child, View focused) { if (!mIsLayoutDirty) { scrollToChild(focused); } else { mChildToScrollTo = focused; } super.requestChildFocus(child, focused); }因为在addViewInner之前调用了requestLayout()方法：@Override public void requestLayout() { mIsLayoutDirty = true; super.requestLayout(); }所以我们在执行requestChildFocus的时候，会进入else的判断，mChildToScrollTo = focused。2.接下来我们继续分析下mParent.requestChildFocus(this, focused)方法？android.view.ViewGroup{ @Override public void requestChildFocus(View child, View focused) { if (DBG) { System.out.println(this + " requestChildFocus()"); } if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) { return; } // Unfocus us, if necessary super.unFocus(focused); // We had a previous notion of who had focus. Clear it. if (mFocused != child) { if (mFocused != null) { mFocused.unFocus(focused); } mFocused = child; } if (mParent != null) { mParent.requestChildFocus(this, focused); } } }首先，我们会判断ViewGroup的descendantFocusability属性，如果是FOCUS_BLOCK_DESCENDANTS值的话，直接就返回了（这部分后面会解释，也是android:descendantFocusability="blocksDescendants"属性能解决自动滑动的原因），我们先来看看if (mParent != null)mParent.requestChildFocus(this, focused)}成立的情况，这里会一直调用，直到调用到ViewRootImpl的requestChildFocus方法@Override public void requestChildFocus(View child, View focused) { if (DEBUG_INPUT_RESIZE) { Log.v(mTag, "Request child focus: focus now " + focused); } checkThread(); scheduleTraversals(); }scheduleTraversals（）会启动一个runnable，执行performTraversals方法进行view树的重绘制。3.那么ScrollView为什么会滑到获取焦点的子view的位置了？答：通过上面的分析，我们可以看到当Scrollview中包含有焦点的view的时候，最终会执行view树的重绘制，所以会调用view的onLayout方法，我们看下ScrollView的onLayout方法android.view.ScrollView{ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); ...... if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) { scrollToChild(mChildToScrollTo); } mChildToScrollTo = null; ...... } }从第一步我们可以看到，我们在requestChildFocus方法中，是对mChildToScrollTo进行赋值了，所以这个时候，我们会进入到if判断的执行，调用scrollToChild(mChildToScrollTo)方法：private void scrollToChild(View child) { child.getDrawingRect(mTempRect); offsetDescendantRectToMyCoords(child, mTempRect); int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect); if (scrollDelta != 0) { scrollBy(0, scrollDelta); } }很明显，当前的方法就是将ScrollView移动到获取制定的view当中，在这里我们可以明白了，为什么ScrollView会自动滑到获取焦点的子view的位置了。4.为什么在ScrollView的子viewGroup中增加android:descendantFocusability=”blocksDescendants”属性能阻止ScrollView的自动滑动呢？答：如第一步所说的，view的绘制原理：是view树的层级绘制，是绘制树的最顶端，也就是子view，然后父view绘制的机制，所以我们在ScrollView的直接子view设置android:descendantFocusability=”blocksDescendants”属性的时候，这个时候直接return了,就不会再继续执行父view也就是ScrollView的requestChildFocus(View child, View focused)方法了，导致下面的自动滑动就不会触发了。 @Override public void requestChildFocus(View child, View focused) { ...... if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) { return; } ...... if (mParent != null) { mParent.requestChildFocus(this, focused); } }5.相信在这里有不少人有疑问了：如果是按照博主你的解释，是不是在ScrollView上面加android:descendantFocusability=”blocksDescendants”属性也能阻止自动滑动呢？答：按照前面的分析的话，似乎是可以的，但是翻看ScrollView的源码，我们可以看到private void initScrollView() { mScroller = new OverScroller(getContext()); setFocusable(true); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setWillNotDraw(false); final ViewConfiguration configuration = ViewConfiguration.get(mContext); mTouchSlop = configuration.getScaledTouchSlop(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); }当你开心的设置android:descendantFocusability=”blocksDescendants”属性以为解决问题了，但是殊不知人家ScrollView的代码里面将这个descendantFocusability属性又设置成了FOCUS_AFTER_DESCENDANTS，所以你在xml中增加是没有任何作用的。6.从上面我们分析了，ScrollView一加载就会滑动到获取焦点的子view的位置了，也明白了增加android:descendantFocusability="blocksDescendants"属性能阻止ScrollView会自动滚动到获取焦点的子view的原因，但是为什么在获取焦点的子view外面套一层view，然后增加focusableInTouchMode=true属性也可以解决这样的滑动呢？答：我们注意到，调用addViewInner方法的时候，会先判断view.hasFocus()，其中view.hasFocus()的判断有两个规则：1.是当前的view在刚显示的时候被展示出来了，hasFocus()才可能为true；2.同一级的view有多个focus的view的话，那么只是第一个view获取焦点。 如果在布局中view标签增加focusableInTouchMode=true属性的话，意味这当我们在加载的时候，标签view的hasfocus就为true了，然而当在获取其中的子view的hasFocus方法的值的时候，他们就为false了。（这就意味着scrollview虽然会滑动，但是滑动到添加focusableInTouchMode=true属性的view的位置，如果view的位置就是填充了scrollview的话，相当于是没有滑动的，这也就是为什么在外布局增加focusableInTouchMode=true属性能阻止ScrollView会自动滚动到获取焦点的子view的原因）所以在外部套一层focusableInTouchMode=true并不是严格意义上的说法，因为虽然我们套了一层view，如果该view不是铺满的scrollview的话，很可能还是会出现自动滑动的。所以我们在套focusableInTouchMode=true属性的情况，最好是在ScrollView的直接子view 上添加就可以了。总结通过上面的分析，其实我们可以得到多种解决ScrollView会自动滚动到获取焦点的子view的方法，比如自定义重写Scrollview的requestChildFocus方法，直接返回return，就能中断Scrollview的自动滑动，本质上都是中断了ScrollView重写的方法requestChildFocus的进行，或者是让Scrollview中铺满ScrollView的子view获取到焦点，这样虽然滑动，但是滑动的距离只是为0罢了，相当于没有滑动罢了。** 同理我们也可以明白，如果是RecyclerView嵌套了RecyclerView，导致自动滑动的话，那么RecyclerView中也应该重写了requestChildFocus，进行自动滑动的准备。也希望大家通过阅读源码自己验证。整理下3种方法： 第一种. 第二种. 第三种.public class StopAutoScrollView extends ScrollView { public StopAutoScrollView(Context context) { super(context); } public StopAutoScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public StopAutoScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void requestChildFocus(View child, View focused) { } }如果大家还有更好的解决方案，可以拿出来大家探讨，要是文章有不对的地方，欢迎拍砖。如果你们觉得文章对你有启示作用，希望你们帮忙点个赞或者关注下，谢谢
1.在布局中写上VideoView<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.constraintlayout.widget.ConstraintLayout>2.activity中代码 mMediaController = new MediaController(this); //我把文件写到缓存中了,FileIOUtils是blankj的 //https://github.com/Blankj/AndroidUtilCode String cacheVideoPath = new File(getCacheDir(), "boot_animation.mp4").getPath(); if (!FileUtils.isFileExists(cacheVideoPath)) { try { InputStream is = getResources().getAssets().open("boot_animation.mp4");//文件在assets下 FileIOUtils.writeFileFromIS(cacheVideoPath, is); } catch (Exception e) { e.printStackTrace(); } } videoView.setVideoPath(cacheVideoPath); videoView.setMediaController(mMediaController); videoView.seekTo(0); videoView.requestFocus(); videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { doWork();//播放完我写了跳到其他页面 } }); videoView.start();
最近几天做的一个项目需要悬浮框,用popupwindow做的,用着好好的,前两天换了一下模拟器,今天突然发现不显示了,刚开始以为出现了什么异常,排查发现没有异常,bing了一下,原来是popupwindow不设置宽高在有些机型上会出现不显示的情况,其实是显示了,但是没有尺寸.popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);加上如上代码,好了,记录一下
疫情期间在家办公,AndroidStudio提示更新就立马更新了,启动图耳目一新,但是遇到个bug,就是build窗口的中文显示乱码了,第一时间找了一下可能还没有多少人更新,没找到解决方案,2020.2.29(今年又闰年啊)这天抱着试一试的心态又找了一下,一下就找到了,试了一下果然有效,只摘抄了最终方案,记录一下,感谢原文的大佬. ------------分割线--------------- 点击Help—>Edit Custom VM Options 然后在打开的文件中添加一句 -Dfile.encoding=UTF-8 然后重启Android Studio -------------分割线------------------ 出处:https://blog.csdn.net/qq_20328181/article/details/104537152