帮酷LOGO
  • 显示原文与译文双语对照的内容
文章标签:lists  Light  lis  fast  列表  Super  SUP  
Super-fast, super-lightweight sectioned lists for Android

  • 源代码名称:SuperSaiyanScrollView
  • 源代码网址:http://www.github.com/nolanlawson/SuperSaiyanScrollView
  • SuperSaiyanScrollView源代码文档
  • SuperSaiyanScrollView源代码下载
  • Git URL:
    git://www.github.com/nolanlawson/SuperSaiyanScrollView.git
  • Git Clone代码到本地:
    git clone http://www.github.com/nolanlawson/SuperSaiyanScrollView
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/nolanlawson/SuperSaiyanScrollView
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
  • SuperSaiyanScrollView

    版本 1.2.0 ( 变更日志 )

    Android的超级快速,超轻量的切片列表。

    Screenshot

    在 HTC Magic ( Eclair ) 和 Galaxy Nexus ( Jelly Bean ) 上的 SuperSaiyanScrollView。

    作者

    Nolan Lawson

    许可证

    Apache 2.0

    安装

    Eclipse

    克隆源代码:

    git clone https://github.com/nolanlawson/SuperSaiyanScrollView.git

    然后将 supersaiyan-scrollview 文件夹作为库项目依赖项添加到你自己的项目中。 如果你以前从未使用过Android库,那么这里是一个不错的屏幕截图教程,或者你可以阅读官方文档。

    如果你使用混淆器,请将以下内容添加到你的proguard.cfg ( Gradle自动处理这里问题) 中:

    -keep public class com.nolanlawson.supersaiyan.widget.*
    Maven
    <dependency>
     <groupId>com.nolanlawson</groupId>
     <artifactId>supersaiyan-scrollview</artifactId>
     <version>1.2.0</version>
    </dependency>
    Gradle
    compile 'com.nolanlawson:supersaiyan-scrollview:1.2.0@aar'

    动机

    快速滚动分段列表是Android中最常见的用户界面模式之一,但仍然是很痛苦的。 stock SDK中没有什么提供这种功能。

    SuperSaiyanScrollView使用闪电快速界面元素和 helper 功能来营救,以方便使用分片列表。

    为什么是"超级 saiyan"因为:?

    • 我成功了所以我去 NAME 那里。
    • 它超快,超级强大,并且启动了( 库存)的android。

    Their power levels are definitely over 9000.

    用法

    在布局XML文件中,在 ListView 周围添加一个 SuperSaiyanScrollView:

    <com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView
     android:id="@+id/scroll"android:layout_width="match_parent"android:layout_height="match_parent">
     <ListViewandroid:id="@android:id/list"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none"/>
    </com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView>

    ( 我喜欢设置 android:scrollbars="none",删除无处不在的灰色滚动条,并使用"快速"蓝色滚动条。)

    接下来,包装你现有的Adapter ( 比如。 SectionedListAdapter 中的ArrayAdapter )。 SectionedListAdapter 使用一个流畅的"生成器"Pattern,类似于 AlertDialog.Builder:

    SectionedListAdapter<MyCoolAdapter> adapter = 
     SectionedListAdapter.Builder.create(this, myCoolAdapter)
    . setSectionizer(newSectionizer<MyCoolListItem>(){
     @OverridepublicCharSequencetoSection(MyCoolListItemitem) {
     return item.toSection();
     }
     })
    . sortKeys()
    . sortValues()
    . build();

    示例

    让我们看看一些简单的例子,它们应该演示 SuperSaiyanScrollView的简单性和灵活性。 这些应用程序的源代码包含在GitHub项目中,你可以在这里下载 APKs:

    示例 #1: 国家

    在本例中,我们有一个国家列表,我们希望按照大陆排序。 完成的应用程序如下所示:

    Screenshot

    我们有一个简单的国家对象:

    publicclassCountry {
     privateString name;
     privateString continent;
     /* getters and setters.. . */@OverridepublicStringtoString() {
     return name;
     }
    }

    我们使用一个基本的ArrayAdapter<Country> 来显示这些国家:

    ArrayAdapter<Country> adapter =newArrayAdapter<Country>(
     this, 
     android.R.layout.simple_spinner_item, 
     countries);

    接下来,我们将它包装在一个 SectionedListAdapter 中。 在本例中,我们希望由他们的大陆分区国家,按 NAME 排序大洲,并按名称排序国家:

    sectionedAdapter = 
     SectionedListAdapter.Builder.create(this, adapter)
    . setSectionizer(newSectionizer<Country>(){
     @OverridepublicCharSequencetoSection(Countryinput) {
     return input.getContinent();
     }
     })
    . sortKeys()
    . sortValues(newComparator<Country>() {
     publicintcompare(Countrylhs, Countryrhs) {
     return lhs.getName().compareTo(rhs.getName());
     }
     })
    . build();

    Sectionizer 是一个简单回调,它为给定列表项提供一个节 NAME。 这是一个 HashMap 查询。数据库查询或者一个简单的getter ( 在本示例中)。

    请注意,键( 例如。 节标题) 和值( 例如。 列表内容可以单独排序,也可以根本不排序。 默认情况下,根据输入顺序对它们进行排序。

    现在,让我们尝试动态更改部分 ! 在操作栏中,用户可以在字母排序和大洲排序之间进行 switch:

    alphabetic sorting vs. continent sorting

    为此,我们首先获取对 SuperSaiyanScrollView的引用:

    SuperSaiyanScrollView superSaiyanScrollView = 
     (SuperSaiyanScrollView) findViewById(R.id.scroll);

    然后,当用户选择字母排序时,我们将调用以下函数:

    privatevoid sortAz() {
     // use the built-in A-Z sectionizer sectionedAdapter.setSectionizer(
     Sectionizers.UsingFirstLetterOfToString);
     // refresh the adapter and scroll view sectionedAdapter.notifyDataSetChanged();
     superSaiyanScrollView.refresh();
    }

    请注意,只要 SectionedListAdapterSuperSaiyanScrollView的内容发生更改,就需要通知它们。

    接下来,当用户切换回大陆排序时,我们将调用这里函数:

    privatevoid sortByContinent() {
     // use the by-continent sectionizer sectionedAdapter.setSectionizer(newSectionizer<Country>(){
     @OverridepublicCharSequencetoSection(Countryinput) {
     return input.getContinent();
     }
     });
     // refresh the adapter and scroll view sectionedAdapter.notifyDataSetChanged();
     superSaiyanScrollView.refresh();
    }

    请注意,你不需要亲自调用 adapter.sort() 或者 Collections.sort()SectionedListAdapter 处理所有的事情,而且它没有修改底层适配器,这意味着视图生成是快速的。

    暗色主题

    不喜欢光线叠加? 将你的底纹放在XML中,并设置 myapp:ssjn_overlayTheme="dark":

    Screenshot

    黑色头发或者浅色头发- 选择是你的。

    示例 #2: Pokémon

    这个例子展示了 SuperSaiyanScrollView的一些高级功能。 我们有三个不同的sortings,覆盖框的大小改变以适合文本大小,我们可以动态隐藏。

    Screenshot

    按区域排序,按字母顺序排列的字母 vs。

    首先,可以在XML中配置覆盖的大小。 在本例中,我们从一个字母的字母排序开始,因这里我们希望覆盖比普通的更小一些。

    将一个命名空间添加到布局XML中的root XML标记中:

    <RelativeLayout. . .
     xmlns:myapp="http://schemas.android.com/apk/res/com.example.example1". . .
    > 
    </RelativeLayout>

    接下来,使用前缀为 ssjn_的值来定义覆盖的大小:

    <com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView
    . . .
     myapp:ssjn_overlaySizeScheme="normal">
     <ListView. . .
    />
    </com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView>

    我包括内置方案 small ( 对于一个字母)。normal ( 对于大多数用例) 和 largexlarge ( 更长的章节标题)。 支持最多两行( 由 n 分隔)的节标题。

    Screenshot

    小,普通,大,大屏幕覆盖在我的AMG日内瓦应用程序中。

    如果需要,还可以手动指定字体大小,宽度,高度和文本颜色:

    <com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView
    . . .
     myapp:ssjn_overlayWidth="400dp"myapp:ssjn_overlayHeight="200dp"myapp:ssjn_overlayTextSize="12sp"myapp:ssjn_overlayTextColor="@android:color/black"> 
     <ListView. . .
    />
    </com.nolanlawson.supersaiyan.widget.SuperSaiyanScrollView>

    现在,在Java源代码中,我们有一个 PocketMonster 对象:

    publicclassPocketMonster {
     privateString uniqueId;
     privateint nationalDexNumber;
     privateString type1;
     privateString type2;
     privateString name;
     /* getters and setters */@OverridepublicStringtoString() {
     return name;
     }
    }

    我们有一个简单的PocketMonsterAdapter 来定义如何在列表中显示怪物:

    publicclassPocketMonsterAdapter 
     extendsArrayAdapter<PocketMonster> {
     // Constructors...@OverridepublicViewgetView(intpos, Viewview, 
     ViewGroupparent) {
     PocketMonster monster = 
     (PocketMonster) getItem(pos);
     /* Create and style the view... */return view;
     }
    }

    我们将这里适配器包装在 SectionedListAdapter 中,默认情况下,该适配器会按字母顺序对所有内容进行分区和排序:

     adapter =SectionedListAdapter.Builder.create(this, subAdapter)
    . setSectionizer(Sectionizers.UsingFirstLetterOfToString)
    . sortKeys()
    . sortValues(newComparator<PocketMonster>(){
     @Overridepublicintcompare(PocketMonsterlhs, 
     PocketMonsterrhs) {
     return lhs.getName().compareToIgnoreCase(
     rhs.getName());
     }})
    . build();

    注意,我们同时调用 sortKeys()sortValues(),因为我们希望按字母顺序排列节标题和 Pokémon。 由于 PocketMonster 没有实现 Comparable,我们定义了一个定制的Comparator

    现在,假设我们要按区域组织 Pokémon:

    Pokémon sorted by region.

    一些快速背景:Pokémon由它们的"国家身份证"订购一个整数值从 1 ( Bulbasaur ) 开始,并且最大值达 718 ( Zygarde )。 每次天堂发布新一代Pokémon游戏时,他们增加了 100个新怪物,设置了新的"区域"和bazillion新的Pokémon玩具。

    基本上,我们可以从Pokémon的ID中确定区域。 我们将定义一个新的Sectionizer,当用户选择"按区域排序"时,它将被调用:

    privatevoid sortByRegion() {
     adapter.setSectionizer(newSectionizer<PocketMonster>() {
     @OverridepublicCharSequencetoSection(PocketMonsterinput) {
     int id = input.getNationalDexNumber();
     // Kanto region will appear first, followed // by Johto, Hoenn, Sinnoh, Unova, and Kalosif (id <=151) {
     return"Kanto (Generation 1)";
     } elseif (id <=251) {
     return"Johto (Generation 2)";
     } elseif (id <=386) {
     return"Hoenn (Generation 3)";
     } elseif (id <=493) {
     return"Sinnoh (Generation 4)";
     } elseif (id <=649) {
     return"Unova (Generation 5)";
     } else {
     return"Kalos (Generation 6)";
     }
     }
     });
     // uses the nat'l pokedex order, since // that's the original input order adapter.setKeySorting(Sorting.InputOrder);
     adapter.setValueSorting(Sorting.InputOrder);
     scrollView.setOverlaySizeScheme(
     OverlaySizeScheme.Large);
     // refresh the adapter and scroll view adapter.notifyDataSetChanged();
     scrollView.refresh();
    }

    注意,我们已经将密钥和值排序更改为 Sorting.InputOrder,因为现在我们要通过它们的国家,订购 Pokémon。 ( 一个自定义 Comparator 也可以完成这里操作。) 这里外,我们增加了覆盖的大小以适应较长的文本。

    现在,假设我们想要按类型组织 Pokémon。 每个Pokémon至少有一个元素类型( 如"火"或者或或者"水"),但有些则有两个。 我们希望在多个类别中列出 Pokémon,这样它们可以在列表中出现多次。

    为此,我们将定义一个 MultipleSectionizer,而不是常规的Sectionizer:

    privatevoid sortByType() {
     adapter.setMultipleSectionizer(
     newMultipleSectionizer<PocketMonster>() {
     @OverridepublicCollection<? extends CharSequence>toSections(
     PocketMonstermonster) {
     String type1 = monster.getType1();
     String type2 = monster.getType2();
     if (!TextUtils.isEmpty(type2)) { // two typesreturnArrays.asList(type1, type2);
     } else { // one typereturnCollections.singleton(type1);
     }
     }
     });
     adapter.setKeySorting(Sorting.Natural);
     adapter.setValueSorting(Sorting.InputOrder);
     scrollView.setOverlaySizeScheme(OverlaySizeScheme.Normal);
     // refresh the adapter and scroll view adapter.notifyDataSetChanged();
     scrollView.refresh();
    }

    注意,键排序再次改变,这一次是 Sorting.Natural,只是按字母顺序排序。 值排序已经改为 Sorting.InputOrder,因为我们已经决定按它的国家id对Pokémon进行排序。

    这里操作按预期方式运行:

    Screenshot

    Pokémon按类型排序

    注意,Charizard出现在"火灾"和"飞行"部分中,因为他有两种类型。

    这里示例应用程序还显示如何禁用节标题或者截面覆盖,以防你不喜欢它们。 这些值也可以在 Builder 链期间使用 hideSectionTitles()hideSectionOverlays() 进行设置。

    Screenshot

    隐藏覆盖和隐藏节标题的比较

    1.2.0 !

    感谢 michaldarda的一些出色工作,现在你可以为 SectionTitleAdapter 指定定制的SectionTitleAdapter 或者布局。 如果使用布局,则应该是具有属性的XML布局资源 android:id="@+id/list_header_title" 指示标题文本。 ( 默认的可以在这里找到,如果你想修改它,请在这里。)

    importcom.nolanlawson.supersaiyan.SectionTitleAdapter;
    sectionedAdapter =SectionedListAdapter.Builder.create(this, subAdapter)
    . setSectionTitleLayout(R.layout.my_layout_id)
     // alternative version. setSectionTitleAdapter(newMySubclassOfSectionTitleAdapter()) 
    . build();

    详细信息

    请参见原始的博客文章以了解一些历史的洞察力。

    这个项目最初源于我自己的 CustomFastScrollViewDemo插件,它是基于Android应用程序的修改。 我找不到原始来源,也找不到原始作者。 但对你来说,神秘的陌生人 !

    变更日志

    • 1.2.0
      • 指定自定义列表头( #7 )
      • 修复细节未刷新( #8 )
    • 1.1.1
      • 修复没有XML属性时的潜在问题( #3 )
    • 1.1.0
      • 转换为 Gradle
      • 添加深色主题( #1 )
    • 1.0.0
      • 初始版本。


    文章标签:SUP  Light  fast  lis  列表  Super  lists  

    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语