背景
我正在尝试模仿 Lollipop 的联系人应用程序显示联系人首字母的固定标题的方式,正如我所写的here https://stackoverflow.com/q/27621425/878126.
问题
由于原始代码(发现here http://code.google.com/p/android-playground/source/checkout,在“PinnedHeaderListViewSample”文件夹中)不显示除英文以外的字母,我不得不稍微更改代码,但这还不够。标题本身也是如此,它现在必须位于左侧,而不是位于行上方。
一切工作正常,直到我在 RTL 语言(在我的例子中是希伯来语)上对其进行了测试,同时设备的区域设置也更改为 RTL 语言(在我的例子中是希伯来语)。
由于某种原因,滚动和标题本身都变得非常奇怪,奇怪的是它发生在某些设备/Android 版本上。
例如,在带有 Kitkat 的 Galaxy S3 上,滚动和滚动条完全错误(我滚动到顶部,但滚动条的位置在中间)。
在搭载 Android 4.2.2 的 LG G2 上,也存在此问题,但它也不会显示标题(固定标题除外),尤其是希伯来语的标题。
在 Galaxy S4 和华为 Ascend P7(均运行 Kitkat)上,无论我做什么,一切都运行良好。
简而言之,特殊场景是:
- 使用 pinnedHeaderListView
- 让设备使用 RTL 语言环境,或者通过开发人员设置进行操作
- 有英语和希伯来语的列表视图项目
- 设置 listView 显示快速滚动条。
- 使用快速滚动器滚动 listView 或像不使用快速滚动器一样滚动。
The code
代码量很大,而且我做了2个POC,其中一个和我一开始的代码有很大不同(为了让它看起来像在Lollipop上)。所以我会尝试显示最少的金额。
编辑:大的 POC 代码可以在 Github 上找到,here https://github.com/AndroidDeveloperLB/ListViewVariants .
“PinnedHeaderActivity.java”
我在顶部的“名称”字段中添加了 2 个希伯来语项目:
"אאא",
"בבב",
在“setupListView”方法中,我使快速滚动条可见:
listView.setFastScrollEnabled(true);
在“NamesAdapter”CTOR 中,我让它支持的不仅仅是英文字母:
public NamesAdapter(Context context, int resourceId, int textViewResourceId, String[] objects) {
super(context, resourceId, textViewResourceId, objects);
final SortedSet<Character> set = new TreeSet<Character>();
for (final String string : objects) {
final String trimmed = string == null ? "" : string.trim();
if (!TextUtils.isEmpty(trimmed))
set.add(Character.toUpperCase(trimmed.charAt(0)));
else
set.add(' ');
}
final StringBuilder sb = new StringBuilder();
for (final Character character : set)
sb.append(character);
this.mIndexer = new StringArrayAlphabetIndexer(objects, sb.toString());
}
“StringArrayAlphabetIndexer.java”
在“getSectionForPosition”方法中,我将其更改为:
public int getSectionForPosition(int position) {
try {
if (mArray == null || mArray.length == 0)
return 0;
final String curName = mArray[position];
// Linear search, as there are only a few items in the section index
// Could speed this up later if it actually gets used.
// TODO use binary search
for (int i = 0; i < mAlphabetLength; ++i) {
final char letter = mAlphabet.charAt(i);
if (TextUtils.isEmpty(curName) && letter == ' ')
return i;
final String targetLetter = Character.toString(letter);
if (compare(curName, targetLetter) == 0)
return i;
}
return 0; // Don't recognize the letter - falls under zero'th section
} catch (final Exception ex) {
return 0;
}
}
列表项.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/list_item_header" />
<include
layout="@android:layout/simple_list_item_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp" />
</FrameLayout>
<View
android:id="@+id/list_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:drawable/divider_horizontal_dark" />
</LinearLayout>
列表项标题.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/header_text"
android:layout_width="25dip"
android:layout_height="25dip"
android:textStyle="bold"
android:background="@color/pinned_header_background"
android:textColor="@color/pinned_header_text"
android:textSize="14sp"
android:paddingLeft="6dip"
android:gravity="center" />
这里有两张截图,一张看起来不太好,另一张看起来还不错:
Galaxy S3 kitkat 和 LG G2 4.2.2 - 不显示希伯来语标题,并且在底部附近有奇怪的滚动(与滚动的其余部分相比,到达底部的速度非常快):
Galaxy S4 kitkat - 显示标题很好,但底部的滚动很奇怪:
For some reason, the Galaxy S4 didn't mirror the UI as it should, even though I've chosen it on the developer options, so it might also be the reason for why it showed the headers fine.
我尝试过的
除了尝试我制作的 2 个 POC(一个与 Material Design 风格更相似并且更复杂)之外,我还尝试了各种使用布局的方法,并且还尝试使用 LayoutDirection 来强制要显示的标题。
更难的问题是解决快速滚动条,它在更复杂的 POC 上工作起来非常奇怪,在简单的 POC 上工作起来有点奇怪(在底部附近快速滚动)。
问题
解决这些问题的正确方法是什么?
为什么 RTL 对于这种类型的 UI 存在问题?
编辑:似乎即使是 Google 的示例也不能在简单的 ListView 上很好地处理 RTL 项目:
http://developer.android.com/training/contacts-provider/retrieve-names.html
当它有希伯来语联系人时,滚动条就会变得“疯狂”。