小编S F*_*itz的帖子

支持库中的Snackbar不包含OnDismissListener()?

我想实现最新设计支持库中包含的新Snackbar,但它的提供方式似乎与我的反直觉相比,而且我认为很多其他人使用它.

当用户执行重要操作时,我希望允许他们通过Snackbar撤消它,但似乎没有办法检测它何时被解除以执行操作.我有意义的做法如下:

  1. 用户采取行动.
  2. 显示Snackbar并更新UI,就像操作已完成一样(即看起来数据已发送到数据库,但实际上还没有).
  3. 如果用户按下"撤消",则还原UI更改.如果没有,当Snackbar被解散时,它将发送数据.

但是因为我没有看到任何可访问的OnDismissListener,所以我必须:

  1. 用户采取行动.
  2. 立即将信息发送到数据库并更新UI.
  3. 如果用户按下"撤消",则向数据库发送另一个调用以删除刚刚添加的数据并恢复UI更改.

我真的想避免不得不对数据库进行两次调用,只需在应用程序知道它是安全的时候发送一个(用户已经避免按"撤消").我注意到在第三方库中通过EventListener实现了这一点,但我真的很想坚持使用Google库.

android android-support-library android-design-library android-snackbar

20
推荐指数
1
解决办法
6231
查看次数

NestedScrollView的fullScroll(View.FOCUS_UP)无法正常工作

我有一个NestedScrollView填充了一个垂直的LinearLayout,它本身有一堆各种视图类型的子项:多个TextViews,两个静态GridViews,甚至一个FrameLayout来显示所有这些下面的片段.

当按下后退按钮时,如果用户滚动到某个点以下,而不是完成活动,则调用"scrollToTop"方法:

public static void scrollToTop(final NestedScrollView scrollview) {
    new Handler().postDelayed(new Runnable() {
        public void run() {
            scrollview.fullScroll(NestedScrollView.FOCUS_UP);
        }
    }, 200);
}
Run Code Online (Sandbox Code Playgroud)

这适用于我的应用程序的早期版本,该版本位于Play商店中.但现在,在更新我的应用程序以定位Android Oreo(并将支持库更新到版本26.0.2)之后,它似乎从NestedScrollView的原始滚动位置下方开始滚动,而不是滚动到顶部,并停止它的位置.所以它只是看起来像一个奇怪的口吃.然而,在某些位置,它确实滚动到顶部(尽管非常罕见且不一致),而其他位置实际上滚动到底部,出于什么原因我不明白.

我一直在试验视图的可聚焦性,但无济于事.例如,我读到静态GridViews可能会在滚动时中断焦点.我也尝试了各种不同的方法来向上滚动,例如

scrollview.pageScroll(View.FOCUS_UP);
Run Code Online (Sandbox Code Playgroud)

scrollview.smoothScrollTo(0,0);
Run Code Online (Sandbox Code Playgroud)

但似乎没有任何效果.这次支持库有什么问题吗?

android android-nestedscrollview

11
推荐指数
3
解决办法
4225
查看次数

TabHost中的Horizo​​ntalScrollView在末尾添加额外的空间

为了在片段之间轻松切换,我将Horizo​​ntalScrollView嵌入到我的Tab布局中,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <HorizontalScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fillViewport="true"
            android:scrollbars="none" >

            <TabWidget android:id="@android:id/tabs" 
                android:layout_height="wrap_content" 
                android:layout_width="wrap_content">
            </TabWidget>
        </HorizontalScrollView>
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</TabHost>
Run Code Online (Sandbox Code Playgroud)

但是在我的代码中添加Fragments(如下所示)之后,在Horizo​​ntalScrollView的末尾会突然显示一些额外的空格:

滚动之前

滚动之前

滚动后

滚动后

代码非常复杂,但我会尝试展示重要的部分.

{
    mTabHost = (TabHost) childLayout.findViewById(android.R.id.tabhost);
    mTabHost.setup();
    FrameLayout tabsFL = (FrameLayout) childLayout.findViewById(android.R.id.tabcontent);
    tabsFL.setId(TABS_FRAME_ID);

    for (int i = 0; i < list.size(); i++) {
        mTabHost.addTab(newTab(String.valueOf(i), list.get(i).getTitle(), tabsFL.getId()));
    }

    mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
        @Override
        public void onTabChanged(String tabId) {
        updateTab(tabId, Integer.parseInt(tabId), list);
        }
    });

    //manually load first fragment …
Run Code Online (Sandbox Code Playgroud)

android horizontalscrollview android-fragments android-tabs

9
推荐指数
1
解决办法
2731
查看次数

getString(int resId,Object ... formatArgs)方法中参数的样式文本

我有两个String资源:

<string name="give_us_feedback">Give us feedback at %1$s if you want to make the app even better!</string>  
<string name="email">info@mycompany.com</string>
Run Code Online (Sandbox Code Playgroud)

我想将电子邮件部分设置为蓝色和下划线,以指示用户可以单击它(整个TextView,而不仅仅是电子邮件文本).我知道使用SpannableString来为文本着色,但是当我通过getString(int resId,Object ... formatArgs)组合两个字符串时它似乎不起作用,可能是因为getString()将执行强制转换或.toString ()正在发送的对象上.这是不起作用的:

TextView emailTV = new TextView(this);
SpannableString email = new SpannableString(getString(R.string.email));
email.setSpan(new UnderlineSpan(), 0, email.length() - 1, 0);
email.setSpan(new ForegroundColorSpan(Color.BLUE), 0, email.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
String feedback = getString(R.string.give_us_feedback, email);
emailTV.setText(feedback);
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

string android textview spannablestring

9
推荐指数
1
解决办法
2687
查看次数

如何在代码中找到所需的Android Marshmallow运行时权限?

我正准备将我的应用程序定位到Android 6.0 Marshmallow.

将目标api设置为23时,应用程序会在启动时立即崩溃.logcat输出中没有有用的信息.(它给出了一个"请求的窗口不存在"IllegalStateException,但是,实际上没有什么比类名或行号更有用.)

这很好(不是真的),我最终将其缩小到我的启动活动,在那里我获得了用户的设备IMEI代码(TelephonyManager.getDeviceId()).需要添加运行时权限请求.我理解这一点.

但是,应用程序在众多活动中有60个类,因此需要排序很多代码.如何搜索代码以查找需要运行时权限的所有情况?

当然Google必须想到一种简单的方法让开发人员找到需要权限请求的位置?我想也许注释掉清单中的权限会触发使用权限的编译时错误,或类似的东西,但不是.

我目前的方法是通过浏览应用程序,当它崩溃时,按照我的启动活动进行上述操作,然后慢慢缩小它的位置.这非常低效且耗时.我现在很想把它留在API 22,但我知道迟早要做到这一点.

android android-permissions android-6.0-marshmallow

5
推荐指数
1
解决办法
1093
查看次数

Android R8 找不到方法

我有两个问题。无论哪种方式,我都无法构建发布 apk。当我禁用 R8(更喜欢 proguard)时,构建会永远持续下去(有时会崩溃,引用“内存不足:java 堆空间”),当我启用 R8 时,我收到以下错误:

Unable to find method 'com.android.tools.r8.CompatProguardCommandBuilder.setProguardSeedsConsumer(Lcom/android/tools/r8/StringConsumer;)Lcom/android/tools/r8/R8Command$Builder;'.
Run Code Online (Sandbox Code Playgroud)

我的项目级 build.gradle:

buildscript {
    repositories {
        google()
        mavenLocal()
        jcenter()
        maven { url "https://maven.google.com" }
        maven { url 'http://storage.googleapis.com/r8-releases/raw' }
    }
    dependencies {
        classpath 'com.android.tools:r8:1.5.68'
        classpath 'com.android.tools.build:gradle:3.6.0-alpha09'
        classpath 'com.google.gms:google-services:4.3.1'
        classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.3'
    }
}

allprojects {
    tasks.withType(JavaCompile) {
        options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked"
    }
    repositories {
        google()
        mavenLocal()
        jcenter()
        maven { url "https://maven.google.com" }
    }
    apply plugin: "com.jfrog.artifactory"
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)

而我的项目模块 build.gradle:

apply plugin: …
Run Code Online (Sandbox Code Playgroud)

android android-gradle-plugin android-r8

4
推荐指数
1
解决办法
1175
查看次数

Android SQLiteDatabase语法错误,代码1

我正在根据这个源创建一个SQLiteDatabase ,但是我遇到了一个我无法弄清楚的语法错误.我已经在StackOverflow上看到了关于此的其他帖子,但它们似乎没有帮助.在这些情况下,它们在某处包含一个额外的空格,或者是一个保留字,但我尝试了不同的间距组合,并确保没有保留任何单词.

我唯一能想到的是我在一个数据库中制作了两个表,这是不可接受的吗?以下是导致问题的代码的要点:

//table name
private static final String TABLE_INGREDIENTS = "table_ingredients";
private static final String TABLE_UNITS = "table_units";

//column names
private static final String ING_KEY_ID = "ing_id";
private static final String ING_KEY_NAME = "ing_name";
private static final String ING_KEY_DENSITY = "ing_density";    
private static final String UNIT_KEY_ID = "unit_id";
private static final String UNIT_KEY_NAME = "unit_name";
private static final String UNIT_KEY_BASE_VALUE = "unit_base_value";
private static final String UNIT_KEY_FINAL_VALUE = "unit_final_value";
private static final String UNIT_KEY_IS_WEIGHT = "unit_is_weight";

// …
Run Code Online (Sandbox Code Playgroud)

sqlite android syntax-error

1
推荐指数
1
解决办法
4271
查看次数