Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android开发中遇到的问题记录 #10

Open
Ccixyj opened this issue Jul 9, 2018 · 25 comments
Open

Android开发中遇到的问题记录 #10

Ccixyj opened this issue Jul 9, 2018 · 25 comments

Comments

@Ccixyj
Copy link
Owner

Ccixyj commented Jul 9, 2018

记录在Android开发的问题,包括kotlin
ia 3lknvka 29 pn a74 hl

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 9, 2018

1.Unresolved reference for synthetic view when layout is in library module (无效)

父模块使用子模块的布局,kotlin-android-extensions 是不能直接使用。

//配置文件添加如下:
androidExtensions {
    experimental = true
}

参考stackoverflow的问题
Kotlin Android Extensions的高级用法可以查阅官方文档

现在没有真正的解决办法
KT-22430

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 9, 2018

2. ConstraintLayout (1.1.x) 在 RecyclerView 中高度不正确的问题

ConstraintLayout 修改属性如下:

   android:layout_height="wrap_content"
   app:layout_constraintHeight_default="wrap"
   app:layout_constrainedHeight="true"

主要是 app:layout_constraintHeight_default="wrap" 这条属性

参考:

  1. https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout
  2. https://stackoverflow.com/questions/40850966/wrap-content-view-inside-a-constraintlayout-stretches-outside-the-screen

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 12, 2018

3. canvas drawtext() 方法的注意点

drawtext() 参数的 y 是一 文字的 baseline 为基准的。所以需要画文字背景时需要考虑 计算 fontMetricsdescent / ascent 参数.

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 16, 2018

3. webview 无法加载图片的问题

对于大家来讲WebView肯定很熟悉,因为我们在日常开发中经常用到它。所以对于它的一些基本用法我就不在这啰嗦了,直接进入正题。

我遇到的问题就是在使用WebView加载网页的时候图片不显示(我手机系统是5.1.1),当时出现这个问题我就想当然的以为,是不是给WebView少设置的什么东西。然后百度一下:

mWebview.getSettings().setJavaScriptEnabled(true);//启用js 
mWebview.getSettings().setBlockNetworkImage(false);//解决图片不显示

然后我检查了自己代码,这两句话也明明加了啊,这到底是什么鬼。后面我也加过其它的一些设置,依然没有用。难道是我的访问路径有问题吗,于是我随便找了带图片的网页,使用WebView加载了一下,哎呦我擦,图片显示没毛病啊。看来还真是我的访问路径有问题啊,但是别的都显示没问题,为什么就图片不显示呢。我跟踪断点把访问的路径复制了出来一看,我靠原来访问路径是https的呀。于是我就把矛头指向了https,简单来说,https就是http的安全版,它在http的基础上加入了ssl层。https协议在使用的时候需要申请一个安全证书,我就想是不是安全证书有问题,回头一想假如安全证书有问题,页面应该是直接显示空白才对。问题又出在哪,于是我把网页路径复制到了浏览器打开,然后查看了一下网页源码,发现图片的引用是http的,问题会不会就出在这呢。果然不出所料:

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
 settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

于是在设置WebView的时候加上了这句话,果然问题解决了。在5.0以下的系统即使不加这句话,图片也可以正常显示,亲测有效。

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 20, 2018

4. CoordinatorLayout > CollapsingToolbarLayout 中 需要全屏的处理

  1. xml 中不要出现 android:fitsSystemWindows="true|false"
  2. 使用 ImmersionBar ,并且 设置 immersionBar.titleBar(mToolbar).init()

注意: 父类如统一初始化了 immersionBar 的话,则要添加 immersionBar.reset() 或者复写父类的实现使得 immersionBar 不要初始化

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 24, 2018

5. WebviewJS 交互 方式

使用JsPrompt方式拦截时** 需要记得调用 result?.confirmresult?.cancel()

参考:
Android:你要的WebView与 JS 交互方式 都在这里了

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 24, 2018

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 25, 2018

7. fragment 中 toolbar 的问题

一个 Activity 中含有多个fragment,且每个fragment有toolbar。那么每个fragment的toolbar是不同的实例,但是activity.setSupportActionBar() 后,activity 的 actionbar 只能持有最后设置的 toolbar 实例。

解决方案:

  1. 当前fragment 显示时再次设置activity.setSupportActionBar(),比如在 viewerpager 中。
  2. 去掉 fragment 中的 activity.setSupportActionBar() ,在各自的 fragment 完成各自的初始化,脱离与 activity 的联系。

相关问题:

  1. 关于在Fragment中使用ToolBar导致菜单错乱----惊现巨坑

@Ccixyj Ccixyj changed the title 开发中遇到的问题记录 Android开发中遇到的问题记录 Jul 26, 2018
@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 30, 2018

8.SwipeRefreshLayout 与 CoordinatorLayout 嵌套刷新

嵌套刷新

Appbar相关 AppBarStateChangeListener

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {

    public enum State {
        EXPANDED,
        COLLAPSED,
        IDLE
    }

    private State mCurrentState = State.IDLE;

    @Override
    public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        if (i == 0) {
            if (mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED);
            }
            mCurrentState = State.EXPANDED;
        } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
            if (mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED);
            }
            mCurrentState = State.COLLAPSED;
        } else {
            if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE);
            }
            mCurrentState = State.IDLE;
        }
    }

    public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}

@Ccixyj
Copy link
Owner Author

Ccixyj commented Jul 31, 2018

9. Toolbar 中 标题居中

确保添加了下面的属性:

 <android.support.v7.widget.Toolbar

      <TextView
       android:layout_width="wrap_content"      
       android:layout_gravity="center"
       android:gravity="center"  />

 </android.support.v7.widget.Toolbar>

@Ccixyj
Copy link
Owner Author

Ccixyj commented Aug 2, 2018

10. ViewPager 嵌套 HorizontalScrollView 的滚动处理

自定义 ViewPager ,重写 canScroll()

override fun canScroll(v: View, checkV: Boolean, dx: Int, x: Int, y: Int): Boolean {
        return if (v is HorizontalScrollView) {
            val child = v.getChildAt(0) ?: return super.canScroll(v, checkV, dx, x, y)
            if (child.measuredWidth == v.scrollX + v.width - v.paddingLeft - v.paddingRight) {
                super.canScroll(v, checkV, dx, x, y)
            } else true
        } else super.canScroll(v, checkV, dx, x, y)
    }

其中,要注意 child.measuredWidth == v.scrollX + v.width - v.paddingLeft - v.paddingRight 是处理
滚到底部后触摸事件交还给 ViewPager 处理

参考:
Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)

@Ccixyj
Copy link
Owner Author

Ccixyj commented Aug 3, 2018

11. ConstraintLayout 中 Group 的注意点

group.setGone 没问题。 但是 group.setInvisible 需要手动调用group.updatePreLayout(constraintLayout)
推测原因为 setInvisible 不会调用 updateLayout

@Ccixyj
Copy link
Owner Author

Ccixyj commented Aug 16, 2018

12. GlideTransformation 注意点

GlideFitCenter CenterCrop 都属于 Transformation<T> 类型。如果要添加自定义的 Transformation 时,都需要放入 Transform(vararg transforms) 中。

示例:

//glide 3.x , 4.x 类似 
 Glide.with(this).load(img)
.bitmapTransform(  CenterCrop(viewContext), RoundedCornersTransformation(viewContext, 8, 0))
.into(imageview)

@Ccixyj
Copy link
Owner Author

Ccixyj commented Sep 14, 2018

13. Webview (h5)中 video 全屏播放

在使用 webview ,如何让 video 支持全屏呢?

  1. 首先在对应的 activity 标签中条件旋转的支持。
      android:configChanges="orientation|keyboardHidden|navigation|screenSize"
      android:hardwareAccelerated="true"
      android:screenOrientation="portrait"

同时 在对应布局中添加一个占位 view container

<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <WebView
            android:id="@+id/base_webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/mp_web_progress"
            style="@style/Widget.AppCompat.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="@dimen/material_3dp"
            android:background="@color/transparent"
            android:max="100"
            android:padding="0dp" />

        <!--全屏占位的view container-->
        <FrameLayout
            android:id="@+id/fl_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />

    </FrameLayout>
  1. 确认添加了 WebSetting 相关配置
        webSettings.loadWithOverviewMode = true
  1. 自定义的 WebChromeClient 中复写 onShowCustomView(view: View?, callback: CustomViewCallback?)onHideCustomView() 方法
        private var nVideoView: View? = null
        private var customViewCallback: CustomViewCallback? = null

        override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
            super.onShowCustomView(view, callback)
            super.onShowCustomView(view, callback)
            if (nVideoView != null) {
                callback?.onCustomViewHidden()
                return
            }
            nVideoView = view
            nVideoView?.visibility = View.VISIBLE
            customViewCallback = callback
            // 占位view容器添加nVideoView
            fl_video?.addView(nVideoView)
            fl_video?.visibility = View.VISIBLE
            fl_video?.bringToFront()
            //设置横屏
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            mToolbar.visibility = View.GONE
           immersionBar.fullScreen(true).transparentStatusBar().statusBarDarkFont(false).init()
        }


        // 退出全屏调用此函数
        override fun onHideCustomView() {
            if (nVideoView == null) {
                return
            }
            try {
                customViewCallback?.onCustomViewHidden()
            } catch (e: Exception) {
            }

            nVideoView?.visibility = View.GONE
            // 占位view容器移除nVideoView
            fl_video?.removeView(nVideoView)
            nVideoView = null
            fl_video?.visibility = View.GONE
            // 设置竖屏
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            // 取消全屏
            val attrs = window.attributes
            attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
            window.attributes = attrs
            mToolbar.visibility = View.VISIBLE
          immersionBar.statusBarDarkFont(true, 0.12f).statusBarColor("#F7F7F7").init()
        }

完成。查看效果!!!

@Ccixyj
Copy link
Owner Author

Ccixyj commented Sep 19, 2018

@Ccixyj
Copy link
Owner Author

Ccixyj commented Sep 25, 2018

14.查看 android gradle 源码的一种方式

在 dependencies 加入 testImplementation "com.android.tools.build:gradle:${versions.gradle}" 即可

@Ccixyj
Copy link
Owner Author

Ccixyj commented Oct 10, 2018

15.高德地图POI搜索多个类别

搜索多个类别。多个关键字用“|”分割 。

相关文档:PoiSearch.Query#构造函数

@Ccixyj
Copy link
Owner Author

Ccixyj commented Oct 19, 2018

16.记录一个奇怪的bug,可能是混淆文件写的不正确

kotlin package级别的一个常量导致了android 在打包混淆 时某个依赖包的asstes 文件丢失一部分

private const val UnitTrans = 666.67
导致
nim_keystore
nim_keystore2
丢失
...

@Ccixyj
Copy link
Owner Author

Ccixyj commented Oct 23, 2018

17. NestedScrollView 键盘遮挡的一个解决方案(adjustpan 无效)

项目里可以获取到 keybord 的高度。而且 adjustpan 无效,且 EditTextNestedScrollView底部,所以解决方案如下:

  1. 键盘弹出时添加一个 keybord 高度的 Space,并滑动只底部
setOnKeyboardListener { isPopup, keyboardHeight ->
            KLog.d("setOnKeyboardListener $isPopup $keyboardHeight")
         if (isPopup){
             if (fr is MeetDetailFragment){
                 if (space.parent != null){
                     return@setOnKeyboardListener
                 }
                 space.apply {
                     layoutParams = ViewGroup.MarginLayoutParams(0, keyboardHeight)
                 }
                 //post to queue
                 fr.ll_meet_body.addView(space)
                 fr.nsc_meet_parent?.post {
                     fr.nsc_meet_parent.fullScroll(View.FOCUS_DOWN)
                 }
             }
         }else{
             if (fr is MeetDetailFragment){
                 fr.ll_meet_body.removeView(space)
             }
         }
  1. 键盘关闭时添加一个移除 Space

https://blog.csdn.net/HJF_HUANGJINFU/article/details/61199480

@Ccixyj
Copy link
Owner Author

Ccixyj commented Nov 12, 2018

18. 一行代码帮你检测Android模拟器

https://www.jianshu.com/p/434b3075b5dd

@Ccixyj
Copy link
Owner Author

Ccixyj commented Mar 4, 2019

强制刷新app的依赖

gradlew build --refresh-dependencies

@Ccixyj
Copy link
Owner Author

Ccixyj commented Apr 24, 2019

阿里云推送的坑

Android集成阿里云推送时,如果使用IntentService时,同时也要集成MessageReceiver,否则在进程结束后再次打卡app收不到离线的信息!!!

@Ccixyj
Copy link
Owner Author

Ccixyj commented May 7, 2019

Drawable 多次tint时的问题

DrawableCompat.wrap(drawable) 后tint 需要先 unwrap
DrawableCompat.unwrap<Drawable>(drawable)

@Ccixyj
Copy link
Owner Author

Ccixyj commented May 10, 2019

Android O

1. Service 使用 ContextCompat.startForegroundService(this,serIntent)

ForegroundService 需要构造一个 notification 来确保为前台服务
startForeground( i > 0 , notification)

notification 至少需要 setContentTitlesetSmallIcon

@Ccixyj
Copy link
Owner Author

Ccixyj commented Oct 10, 2019

ADB 操作

1 . adb shell am start -n "package/package+classname"
2. adb shell am force-stop "package"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant