我想实现最新设计支持库中包含的新Snackbar,但它的提供方式似乎与我的反直觉相比,而且我认为很多其他人使用它.
当用户执行重要操作时,我希望允许他们通过Snackbar撤消它,但似乎没有办法检测它何时被解除以执行操作.我有意义的做法如下:
但是因为我没有看到任何可访问的OnDismissListener,所以我必须:
我真的想避免不得不对数据库进行两次调用,只需在应用程序知道它是安全的时候发送一个(用户已经避免按"撤消").我注意到在第三方库中通过EventListener实现了这一点,但我真的很想坚持使用Google库.
android android-support-library android-design-library android-snackbar
我有一个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)
但似乎没有任何效果.这次支持库有什么问题吗?
为了在片段之间轻松切换,我将HorizontalScrollView嵌入到我的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(如下所示)之后,在HorizontalScrollView的末尾会突然显示一些额外的空格:
滚动之前

滚动后

代码非常复杂,但我会尝试展示重要的部分.
{
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) 我有两个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)
有任何想法吗?
我正准备将我的应用程序定位到Android 6.0 Marshmallow.
将目标api设置为23时,应用程序会在启动时立即崩溃.logcat输出中没有有用的信息.(它给出了一个"请求的窗口不存在"IllegalStateException,但是,实际上没有什么比类名或行号更有用.)
这很好(不是真的),我最终将其缩小到我的启动活动,在那里我获得了用户的设备IMEI代码(TelephonyManager.getDeviceId()).需要添加运行时权限请求.我理解这一点.
但是,应用程序在众多活动中有60个类,因此需要排序很多代码.如何搜索代码以查找需要运行时权限的所有情况?
当然Google必须想到一种简单的方法让开发人员找到需要权限请求的位置?我想也许注释掉清单中的权限会触发使用权限的编译时错误,或类似的东西,但不是.
我目前的方法是通过浏览应用程序,当它崩溃时,按照我的启动活动进行上述操作,然后慢慢缩小它的位置.这非常低效且耗时.我现在很想把它留在API 22,但我知道迟早要做到这一点.
我有两个问题。无论哪种方式,我都无法构建发布 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) 我正在根据这个源创建一个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)