From 1d91804dc7943e7149d02141a46c3eb0763e2b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 1 Jan 2014 22:26:19 +0100 Subject: Simple new list implementations, remove library, use simple adapter with headings --- libraries/pinned-section-listview/.gitignore | 6 - libraries/pinned-section-listview/README.md | 75 --- .../example/AndroidManifest.xml | 27 -- .../example/assets/.gitignore | 1 - .../example/ic_launcher-web.png | Bin 45500 -> 0 bytes .../example/libs/android-support-v4.jar | Bin 393154 -> 0 bytes .../example/proguard-project.txt | 20 - .../example/project.properties | 15 - .../example/res/drawable-hdpi/ic_launcher.png | Bin 5819 -> 0 bytes .../example/res/drawable-mdpi/ic_launcher.png | Bin 3479 -> 0 bytes .../example/res/drawable-xhdpi/ic_launcher.png | Bin 7534 -> 0 bytes .../example/res/drawable-xxhdpi/ic_launcher.png | Bin 11732 -> 0 bytes .../example/res/layout/activity_main.xml | 8 - .../example/res/menu/main.xml | 27 -- .../example/res/values-v11/styles.xml | 11 - .../example/res/values-v14/styles.xml | 12 - .../example/res/values/colors.xml | 10 - .../example/res/values/strings.xml | 10 - .../example/res/values/styles.xml | 20 - .../com/hb/examples/PinnedSectionListActivity.java | 285 ------------ .../library/AndroidManifest.xml | 13 - .../library/assets/.gitignore | 1 - .../pinned-section-listview/library/build.gradle | 24 - .../library/proguard-project.txt | 20 - .../library/project.properties | 15 - .../pinned-section-listview/library/res/.gitignore | 1 - .../src/com/hb/views/PinnedSectionListView.java | 513 --------------------- libraries/pinned-section-listview/screen1.png | Bin 23124 -> 0 bytes libraries/pinned-section-listview/screen2.png | Bin 22743 -> 0 bytes libraries/pinned-section-listview/screen3.png | Bin 22885 -> 0 bytes 30 files changed, 1114 deletions(-) delete mode 100644 libraries/pinned-section-listview/.gitignore delete mode 100644 libraries/pinned-section-listview/README.md delete mode 100644 libraries/pinned-section-listview/example/AndroidManifest.xml delete mode 100644 libraries/pinned-section-listview/example/assets/.gitignore delete mode 100644 libraries/pinned-section-listview/example/ic_launcher-web.png delete mode 100644 libraries/pinned-section-listview/example/libs/android-support-v4.jar delete mode 100644 libraries/pinned-section-listview/example/proguard-project.txt delete mode 100644 libraries/pinned-section-listview/example/project.properties delete mode 100644 libraries/pinned-section-listview/example/res/drawable-hdpi/ic_launcher.png delete mode 100644 libraries/pinned-section-listview/example/res/drawable-mdpi/ic_launcher.png delete mode 100644 libraries/pinned-section-listview/example/res/drawable-xhdpi/ic_launcher.png delete mode 100644 libraries/pinned-section-listview/example/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 libraries/pinned-section-listview/example/res/layout/activity_main.xml delete mode 100644 libraries/pinned-section-listview/example/res/menu/main.xml delete mode 100644 libraries/pinned-section-listview/example/res/values-v11/styles.xml delete mode 100644 libraries/pinned-section-listview/example/res/values-v14/styles.xml delete mode 100644 libraries/pinned-section-listview/example/res/values/colors.xml delete mode 100644 libraries/pinned-section-listview/example/res/values/strings.xml delete mode 100644 libraries/pinned-section-listview/example/res/values/styles.xml delete mode 100644 libraries/pinned-section-listview/example/src/com/hb/examples/PinnedSectionListActivity.java delete mode 100644 libraries/pinned-section-listview/library/AndroidManifest.xml delete mode 100644 libraries/pinned-section-listview/library/assets/.gitignore delete mode 100644 libraries/pinned-section-listview/library/build.gradle delete mode 100644 libraries/pinned-section-listview/library/proguard-project.txt delete mode 100644 libraries/pinned-section-listview/library/project.properties delete mode 100644 libraries/pinned-section-listview/library/res/.gitignore delete mode 100644 libraries/pinned-section-listview/library/src/com/hb/views/PinnedSectionListView.java delete mode 100644 libraries/pinned-section-listview/screen1.png delete mode 100644 libraries/pinned-section-listview/screen2.png delete mode 100644 libraries/pinned-section-listview/screen3.png (limited to 'libraries') diff --git a/libraries/pinned-section-listview/.gitignore b/libraries/pinned-section-listview/.gitignore deleted file mode 100644 index ba354bcae..000000000 --- a/libraries/pinned-section-listview/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -bin -gen -.project -.classpath -.settings -.DS_Store diff --git a/libraries/pinned-section-listview/README.md b/libraries/pinned-section-listview/README.md deleted file mode 100644 index e89cde3bb..000000000 --- a/libraries/pinned-section-listview/README.md +++ /dev/null @@ -1,75 +0,0 @@ -Introduction -============ - -Easy to use ListView with pinned sections for Android. Pinned section is a header view which sticks to the top -of the list until at least one item of that section is visible. - -![Alt text](screen1.png)  -![Alt text](screen2.png)  -![Alt text](screen3.png) - -Features -======== -This list properly implements many features which are missing from other implementations. These are - * Fast scroll - * Headers and footers - * Clickable pinned sections - -Besides this it doesn't create any unnecessary views, layouts etc. It's really lean. - -Watch [this video][1] to see `PinnedSectionListView` in action. - -Usage -===== - 1. Replace standard `ListView` with `com.hb.views.PinnedSectionListView` in your `layout.xml` file. - - - - 2. Extend your `ListAdapter` in a way that it implements `PinnedSectionListAdapter` interface, in addition to - what it already implements. Basically you need to add a single `isItemViewTypePinned(int viewType)` - method. This method must return `true` for all view types which have to be pinned. - - // Our adapter class implements 'PinnedSectionListAdapter' interface - class MyPinnedSectionListAdapter extends BaseAdapter implements PinnedSectionListAdapter { - - ... - - // We implement this method to return 'true' for all view types we want to pin - @Override - public boolean isItemViewTypePinned(int viewType) { - return viewType == ; - } - } - -That's all. You are done! A working example can also be found in `example` folder. - -Used by -======= -Let us know if you use this library in your application and we will mention it here. - -[Grocery Sum][2] - -License -======= - - Copyright 2013 Sergej Shafarenka, halfbit.de - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -[1]: http://www.youtube.com/watch?v=mI3DpuoIIhQ -[2]: https://play.google.com/store/apps/details?id=org.codechimp.grocerysum diff --git a/libraries/pinned-section-listview/example/AndroidManifest.xml b/libraries/pinned-section-listview/example/AndroidManifest.xml deleted file mode 100644 index 56621893d..000000000 --- a/libraries/pinned-section-listview/example/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/assets/.gitignore b/libraries/pinned-section-listview/example/assets/.gitignore deleted file mode 100644 index fdffa2a0f..000000000 --- a/libraries/pinned-section-listview/example/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -# placeholder diff --git a/libraries/pinned-section-listview/example/ic_launcher-web.png b/libraries/pinned-section-listview/example/ic_launcher-web.png deleted file mode 100644 index 8bd40412e..000000000 Binary files a/libraries/pinned-section-listview/example/ic_launcher-web.png and /dev/null differ diff --git a/libraries/pinned-section-listview/example/libs/android-support-v4.jar b/libraries/pinned-section-listview/example/libs/android-support-v4.jar deleted file mode 100644 index 65ebaf8dc..000000000 Binary files a/libraries/pinned-section-listview/example/libs/android-support-v4.jar and /dev/null differ diff --git a/libraries/pinned-section-listview/example/proguard-project.txt b/libraries/pinned-section-listview/example/proguard-project.txt deleted file mode 100644 index f2fe1559a..000000000 --- a/libraries/pinned-section-listview/example/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/libraries/pinned-section-listview/example/project.properties b/libraries/pinned-section-listview/example/project.properties deleted file mode 100644 index 1561d7a9a..000000000 --- a/libraries/pinned-section-listview/example/project.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-17 -android.library.reference.1=../library diff --git a/libraries/pinned-section-listview/example/res/drawable-hdpi/ic_launcher.png b/libraries/pinned-section-listview/example/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 3841c3408..000000000 Binary files a/libraries/pinned-section-listview/example/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/libraries/pinned-section-listview/example/res/drawable-mdpi/ic_launcher.png b/libraries/pinned-section-listview/example/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index e65953cce..000000000 Binary files a/libraries/pinned-section-listview/example/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/libraries/pinned-section-listview/example/res/drawable-xhdpi/ic_launcher.png b/libraries/pinned-section-listview/example/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 4ea093d86..000000000 Binary files a/libraries/pinned-section-listview/example/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/libraries/pinned-section-listview/example/res/drawable-xxhdpi/ic_launcher.png b/libraries/pinned-section-listview/example/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 87e928a35..000000000 Binary files a/libraries/pinned-section-listview/example/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/libraries/pinned-section-listview/example/res/layout/activity_main.xml b/libraries/pinned-section-listview/example/res/layout/activity_main.xml deleted file mode 100644 index b641f4c80..000000000 --- a/libraries/pinned-section-listview/example/res/layout/activity_main.xml +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/menu/main.xml b/libraries/pinned-section-listview/example/res/menu/main.xml deleted file mode 100644 index 091b6c770..000000000 --- a/libraries/pinned-section-listview/example/res/menu/main.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/values-v11/styles.xml b/libraries/pinned-section-listview/example/res/values-v11/styles.xml deleted file mode 100644 index 541752f6e..000000000 --- a/libraries/pinned-section-listview/example/res/values-v11/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/values-v14/styles.xml b/libraries/pinned-section-listview/example/res/values-v14/styles.xml deleted file mode 100644 index f20e01501..000000000 --- a/libraries/pinned-section-listview/example/res/values-v14/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/values/colors.xml b/libraries/pinned-section-listview/example/res/values/colors.xml deleted file mode 100644 index b4da27c93..000000000 --- a/libraries/pinned-section-listview/example/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #ffff4444 - #ff99cc00 - #ffffbb33 - #ff33b5e5 - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/values/strings.xml b/libraries/pinned-section-listview/example/res/values/strings.xml deleted file mode 100644 index e9d43a4aa..000000000 --- a/libraries/pinned-section-listview/example/res/values/strings.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Pinned Section Demo - Fast scroll - Add padding - Show shadow - Show Header & Footer - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/res/values/styles.xml b/libraries/pinned-section-listview/example/res/values/styles.xml deleted file mode 100644 index 4a10ca492..000000000 --- a/libraries/pinned-section-listview/example/res/values/styles.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/example/src/com/hb/examples/PinnedSectionListActivity.java b/libraries/pinned-section-listview/example/src/com/hb/examples/PinnedSectionListActivity.java deleted file mode 100644 index 223718a06..000000000 --- a/libraries/pinned-section-listview/example/src/com/hb/examples/PinnedSectionListActivity.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2013 Sergej Shafarenka, halfbit.de - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hb.examples; - -import java.util.Locale; - -import android.annotation.SuppressLint; -import android.app.ListActivity; -import android.content.Context; -import android.graphics.Color; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.SectionIndexer; -import android.widget.TextView; -import android.widget.Toast; - -import com.hb.examples.pinnedsection.R; -import com.hb.views.PinnedSectionListView; -import com.hb.views.PinnedSectionListView.PinnedSectionListAdapter; - -public class PinnedSectionListActivity extends ListActivity implements OnClickListener { - - static class SimpleAdapter extends ArrayAdapter implements PinnedSectionListAdapter { - - private static final int[] COLORS = new int[] { - R.color.green_light, R.color.orange_light, - R.color.blue_light, R.color.red_light }; - - public SimpleAdapter(Context context, int resource, int textViewResourceId) { - super(context, resource, textViewResourceId); - - final int sectionsNumber = 'Z' - 'A' + 1; - prepareSections(sectionsNumber); - - int sectionPosition = 0, listPosition = 0; - for (char i=0; i= sections.length) { - section = sections.length - 1; - } - return sections[section].listPosition; - } - - @Override public int getSectionForPosition(int position) { - if (position >= getCount()) { - position = getCount() - 1; - } - return getItem(position).sectionPosition; - } - - } - - static class Item { - - public static final int ITEM = 0; - public static final int SECTION = 1; - - public final int type; - public final String text; - - public int sectionPosition; - public int listPosition; - - public Item(int type, String text) { - this.type = type; - this.text = text; - } - - @Override public String toString() { - return text; - } - - } - - private boolean hasHeaderAndFooter; - private boolean isFastScroll; - private boolean addPadding; - private boolean isShadowVisible = true; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - if (savedInstanceState != null) { - isFastScroll = savedInstanceState.getBoolean("isFastScroll"); - addPadding = savedInstanceState.getBoolean("addPadding"); - isShadowVisible = savedInstanceState.getBoolean("isShadowVisible"); - hasHeaderAndFooter = savedInstanceState.getBoolean("hasHeaderAndFooter"); - } - initializeHeaderAndFooter(); - initializeAdapter(); - initializePadding(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean("isFastScroll", isFastScroll); - outState.putBoolean("addPadding", addPadding); - outState.putBoolean("isShadowVisible", isShadowVisible); - outState.putBoolean("hasHeaderAndFooter", hasHeaderAndFooter); - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - Item item = (Item) getListView().getAdapter().getItem(position); - if (item != null) { - Toast.makeText(this, "Item " + position + ": " + item.text, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(this, "Item " + position, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.main, menu); - menu.getItem(0).setChecked(isFastScroll); - menu.getItem(1).setChecked(addPadding); - menu.getItem(2).setChecked(isShadowVisible); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_fastscroll: - isFastScroll = !isFastScroll; - item.setChecked(isFastScroll); - initializeAdapter(); - break; - case R.id.action_addpadding: - addPadding = !addPadding; - item.setChecked(addPadding); - initializePadding(); - break; - case R.id.action_showShadow: - isShadowVisible = !isShadowVisible; - item.setChecked(isShadowVisible); - ((PinnedSectionListView)getListView()).setShadowVisible(isShadowVisible); - break; - case R.id.action_showHeaderAndFooter: - hasHeaderAndFooter = !hasHeaderAndFooter; - item.setChecked(hasHeaderAndFooter); - initializeHeaderAndFooter(); - break; - } - return true; - } - - private void initializePadding() { - float density = getResources().getDisplayMetrics().density; - int padding = addPadding ? (int) (16 * density) : 0; - getListView().setPadding(padding, padding, padding, padding); - } - - private void initializeHeaderAndFooter() { - setListAdapter(null); - if (hasHeaderAndFooter) { - ListView list = getListView(); - - LayoutInflater inflater = LayoutInflater.from(this); - TextView header1 = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false); - header1.setText("First header"); - list.addHeaderView(header1); - - TextView header2 = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false); - header2.setText("Second header"); - list.addHeaderView(header2); - - TextView footer = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false); - footer.setText("Single footer"); - list.addFooterView(footer); - } - initializeAdapter(); - } - - @SuppressLint("NewApi") - private void initializeAdapter() { - getListView().setFastScrollEnabled(isFastScroll); - if (isFastScroll) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - getListView().setFastScrollAlwaysVisible(true); - } - setListAdapter(new FastScrollAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1)); - } else { - setListAdapter(new SimpleAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1)); - } - } - - @Override - public void onClick(View v) { - Toast.makeText(this, "Item: " + v.getTag() , Toast.LENGTH_SHORT).show(); - } - -} \ No newline at end of file diff --git a/libraries/pinned-section-listview/library/AndroidManifest.xml b/libraries/pinned-section-listview/library/AndroidManifest.xml deleted file mode 100644 index 2e2ee9173..000000000 --- a/libraries/pinned-section-listview/library/AndroidManifest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/libraries/pinned-section-listview/library/assets/.gitignore b/libraries/pinned-section-listview/library/assets/.gitignore deleted file mode 100644 index fdffa2a0f..000000000 --- a/libraries/pinned-section-listview/library/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -# placeholder diff --git a/libraries/pinned-section-listview/library/build.gradle b/libraries/pinned-section-listview/library/build.gradle deleted file mode 100644 index d77f4746f..000000000 --- a/libraries/pinned-section-listview/library/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.6.3' - } -} - -apply plugin: 'android-library' - - -android { - compileSdkVersion 17 - buildToolsVersion '19' - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src'] - res.srcDirs = ['res'] - } - } -} diff --git a/libraries/pinned-section-listview/library/proguard-project.txt b/libraries/pinned-section-listview/library/proguard-project.txt deleted file mode 100644 index f2fe1559a..000000000 --- a/libraries/pinned-section-listview/library/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/libraries/pinned-section-listview/library/project.properties b/libraries/pinned-section-listview/library/project.properties deleted file mode 100644 index 484dab075..000000000 --- a/libraries/pinned-section-listview/library/project.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-17 -android.library=true diff --git a/libraries/pinned-section-listview/library/res/.gitignore b/libraries/pinned-section-listview/library/res/.gitignore deleted file mode 100644 index fdffa2a0f..000000000 --- a/libraries/pinned-section-listview/library/res/.gitignore +++ /dev/null @@ -1 +0,0 @@ -# placeholder diff --git a/libraries/pinned-section-listview/library/src/com/hb/views/PinnedSectionListView.java b/libraries/pinned-section-listview/library/src/com/hb/views/PinnedSectionListView.java deleted file mode 100644 index 8100ad693..000000000 --- a/libraries/pinned-section-listview/library/src/com/hb/views/PinnedSectionListView.java +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) 2013 Sergej Shafarenka, halfbit.de - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file kt in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hb.views; - -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.GradientDrawable.Orientation; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.SoundEffectConstants; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.accessibility.AccessibilityEvent; -import android.widget.AbsListView; -import android.widget.HeaderViewListAdapter; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.SectionIndexer; - -import com.hb.views.pinnedsection.BuildConfig; - -/** - * ListView, which is capable to pin section views at its top while the rest is still scrolled. - */ -public class PinnedSectionListView extends ListView { - - //-- inner classes - - /** List adapter to be implemented for being used with PinnedSectionListView adapter. */ - public static interface PinnedSectionListAdapter extends ListAdapter { - /** This method shall return 'true' if views of given type has to be pinned. */ - boolean isItemViewTypePinned(int viewType); - } - - /** Wrapper class for pinned section view and its position in the list. */ - static class PinnedSection { - public View view; - public int position; - public long id; - } - - //-- class fields - - // fields used for handling touch events - private final Rect mTouchRect = new Rect(); - private final PointF mTouchPoint = new PointF(); - private int mTouchSlop; - private View mTouchTarget; - private MotionEvent mDownEvent; - - // fields used for drawing shadow under a pinned section - private GradientDrawable mShadowDrawable; - private int mSectionsDistanceY; - private int mShadowHeight; - - /** Delegating listener, can be null. */ - OnScrollListener mDelegateOnScrollListener; - - /** Shadow for being recycled, can be null. */ - PinnedSection mRecycleSection; - - /** shadow instance with a pinned view, can be null. */ - PinnedSection mPinnedSection; - - /** Pinned view Y-translation. We use it to stick pinned view to the next section. */ - int mTranslateY; - - /** Scroll listener which does the magic */ - private final OnScrollListener mOnScrollListener = new OnScrollListener() { - - @Override public void onScrollStateChanged(AbsListView view, int scrollState) { - if (mDelegateOnScrollListener != null) { // delegate - mDelegateOnScrollListener.onScrollStateChanged(view, scrollState); - } - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - - if (mDelegateOnScrollListener != null) { // delegate - mDelegateOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); - } - - // get expected adapter or fail fast - ListAdapter adapter = getAdapter(); - if (adapter == null || visibleItemCount == 0) return; // nothing to do - - final boolean isFirstVisibleItemSection = - isItemViewTypePinned(adapter, adapter.getItemViewType(firstVisibleItem)); - - if (isFirstVisibleItemSection) { - View sectionView = getChildAt(0); - if (sectionView.getTop() == getPaddingTop()) { // view sticks to the top, no need for pinned shadow - destroyPinnedShadow(); - } else { // section doesn't stick to the top, make sure we have a pinned shadow - ensureShadowForPosition(firstVisibleItem, firstVisibleItem, visibleItemCount); - } - - } else { // section is not at the first visible position - int sectionPosition = findCurrentSectionPosition(firstVisibleItem); - if (sectionPosition > -1) { // we have section position - ensureShadowForPosition(sectionPosition, firstVisibleItem, visibleItemCount); - } else { // there is no section for the first visible item, destroy shadow - destroyPinnedShadow(); - } - } - }; - - }; - - /** Default change observer. */ - private final DataSetObserver mDataSetObserver = new DataSetObserver() { - @Override public void onChanged() { - recreatePinnedShadow(); - }; - @Override public void onInvalidated() { - recreatePinnedShadow(); - } - }; - - //-- constructors - - public PinnedSectionListView(Context context, AttributeSet attrs) { - super(context, attrs); - initView(); - } - - public PinnedSectionListView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initView(); - } - - private void initView() { - setOnScrollListener(mOnScrollListener); - mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); - initShadow(true); - } - - //-- public API methods - - public void setShadowVisible(boolean visible) { - initShadow(visible); - if (mPinnedSection != null) { - View v = mPinnedSection.view; - invalidate(v.getLeft(), v.getTop(), v.getRight(), v.getBottom() + mShadowHeight); - } - } - - //-- pinned section drawing methods - - public void initShadow(boolean visible) { - if (visible) { - if (mShadowDrawable == null) { - mShadowDrawable = new GradientDrawable(Orientation.TOP_BOTTOM, - new int[] { Color.parseColor("#ffa0a0a0"), Color.parseColor("#50a0a0a0"), Color.parseColor("#00a0a0a0")}); - mShadowHeight = (int) (8 * getResources().getDisplayMetrics().density); - } - } else { - if (mShadowDrawable != null) { - mShadowDrawable = null; - mShadowHeight = 0; - } - } - } - - /** Create shadow wrapper with a pinned view for a view at given position */ - void createPinnedShadow(int position) { - - // try to recycle shadow - PinnedSection pinnedShadow = mRecycleSection; - mRecycleSection = null; - - // create new shadow, if needed - if (pinnedShadow == null) pinnedShadow = new PinnedSection(); - // request new view using recycled view, if such - View pinnedView = getAdapter().getView(position, pinnedShadow.view, PinnedSectionListView.this); - - // read layout parameters - LayoutParams layoutParams = (LayoutParams) pinnedView.getLayoutParams(); - if (layoutParams == null) { // create default layout params - layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } - - int heightMode = MeasureSpec.getMode(layoutParams.height); - int heightSize = MeasureSpec.getSize(layoutParams.height); - - if (heightMode == MeasureSpec.UNSPECIFIED) heightMode = MeasureSpec.EXACTLY; - - int maxHeight = getHeight() - getListPaddingTop() - getListPaddingBottom(); - if (heightSize > maxHeight) heightSize = maxHeight; - - // measure & layout - int ws = MeasureSpec.makeMeasureSpec(getWidth() - getListPaddingLeft() - getListPaddingRight(), MeasureSpec.EXACTLY); - int hs = MeasureSpec.makeMeasureSpec(heightSize, heightMode); - pinnedView.measure(ws, hs); - pinnedView.layout(0, 0, pinnedView.getMeasuredWidth(), pinnedView.getMeasuredHeight()); - mTranslateY = 0; - - // initialize pinned shadow - pinnedShadow.view = pinnedView; - pinnedShadow.position = position; - pinnedShadow.id = getAdapter().getItemId(position); - - // store pinned shadow - mPinnedSection = pinnedShadow; - } - - /** Destroy shadow wrapper for currently pinned view */ - void destroyPinnedShadow() { - if (mPinnedSection != null) { - // keep shadow for being recycled later - mRecycleSection = mPinnedSection; - mPinnedSection = null; - } - } - - /** Makes sure we have an actual pinned shadow for given position. */ - void ensureShadowForPosition(int sectionPosition, int firstVisibleItem, int visibleItemCount) { - if (visibleItemCount < 2) { // no need for creating shadow at all, we have a single visible item - destroyPinnedShadow(); - return; - } - - if (mPinnedSection != null - && mPinnedSection.position != sectionPosition) { // invalidate shadow, if required - destroyPinnedShadow(); - } - - if (mPinnedSection == null) { // create shadow, if empty - createPinnedShadow(sectionPosition); - } - - // align shadow according to next section position, if needed - int nextPosition = sectionPosition + 1; - if (nextPosition < getCount()) { - int nextSectionPosition = findFirstVisibleSectionPosition(nextPosition, - visibleItemCount - (nextPosition - firstVisibleItem)); - if (nextSectionPosition > -1) { - View nextSectionView = getChildAt(nextSectionPosition - firstVisibleItem); - final int bottom = mPinnedSection.view.getBottom() + getPaddingTop(); - mSectionsDistanceY = nextSectionView.getTop() - bottom; - if (mSectionsDistanceY < 0) { - // next section overlaps pinned shadow, move it up - mTranslateY = mSectionsDistanceY; - } else { - // next section does not overlap with pinned, stick to top - mTranslateY = 0; - } - } else { - // no other sections are visible, stick to top - mTranslateY = 0; - mSectionsDistanceY = Integer.MAX_VALUE; - } - } - - } - - int findFirstVisibleSectionPosition(int firstVisibleItem, int visibleItemCount) { - ListAdapter adapter = getAdapter(); - for (int childIndex = 0; childIndex < visibleItemCount; childIndex++) { - int position = firstVisibleItem + childIndex; - int viewType = adapter.getItemViewType(position); - if (isItemViewTypePinned(adapter, viewType)) return position; - } - return -1; - } - - int findCurrentSectionPosition(int fromPosition) { - ListAdapter adapter = getAdapter(); - - if (adapter instanceof SectionIndexer) { - // try fast way by asking section indexer - SectionIndexer indexer = (SectionIndexer) adapter; - int sectionPosition = indexer.getSectionForPosition(fromPosition); - int itemPosition = indexer.getPositionForSection(sectionPosition); - int typeView = adapter.getItemViewType(itemPosition); - if (isItemViewTypePinned(adapter, typeView)) { - return itemPosition; - } // else, no luck - } - - // try slow way by looking through to the next section item above - for (int position=fromPosition; position>=0; position--) { - int viewType = adapter.getItemViewType(position); - if (isItemViewTypePinned(adapter, viewType)) return position; - } - return -1; // no candidate found - } - - void recreatePinnedShadow() { - destroyPinnedShadow(); - ListAdapter adapter = getAdapter(); - if (adapter != null && adapter.getCount() > 0) { - int firstVisiblePosition = getFirstVisiblePosition(); - int sectionPosition = findCurrentSectionPosition(firstVisiblePosition); - if (sectionPosition == -1) return; // no views to pin, exit - ensureShadowForPosition(sectionPosition, - firstVisiblePosition, getLastVisiblePosition() - firstVisiblePosition); - } - } - - @Override - public void setOnScrollListener(OnScrollListener listener) { - if (listener == mOnScrollListener) { - super.setOnScrollListener(listener); - } else { - mDelegateOnScrollListener = listener; - } - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - super.onRestoreInstanceState(state); - post(new Runnable() { - @Override public void run() { // restore pinned view after configuration change - recreatePinnedShadow(); - } - }); - } - - @Override - public void setAdapter(ListAdapter adapter) { - - // assert adapter in debug mode - if (BuildConfig.DEBUG && adapter != null) { - if (!(adapter instanceof PinnedSectionListAdapter)) - throw new IllegalArgumentException("Does your adapter implement PinnedSectionListAdapter?"); - if (adapter.getViewTypeCount() < 2) - throw new IllegalArgumentException("Does your adapter handle at least two types" + - " of views in getViewTypeCount() method: items and sections?"); - } - - // unregister observer at old adapter and register on new one - ListAdapter oldAdapter = getAdapter(); - if (oldAdapter != null) oldAdapter.unregisterDataSetObserver(mDataSetObserver); - if (adapter != null) adapter.registerDataSetObserver(mDataSetObserver); - - // destroy pinned shadow, if new adapter is not same as old one - if (oldAdapter != adapter) destroyPinnedShadow(); - - super.setAdapter(adapter); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - if (mPinnedSection != null) { - int parentWidth = r - l - getPaddingLeft() - getPaddingRight(); - int shadowWidth = mPinnedSection.view.getWidth(); - if (parentWidth != shadowWidth) { - recreatePinnedShadow(); - } - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - - if (mPinnedSection != null) { - - // prepare variables - int pLeft = getListPaddingLeft(); - int pTop = getListPaddingTop(); - View view = mPinnedSection.view; - - // draw child - canvas.save(); - - int clipHeight = view.getHeight() + - (mShadowDrawable == null ? 0 : Math.min(mShadowHeight, mSectionsDistanceY)); - canvas.clipRect(pLeft, pTop, pLeft + view.getWidth(), pTop + clipHeight); - - canvas.translate(pLeft, pTop + mTranslateY); - drawChild(canvas, mPinnedSection.view, getDrawingTime()); - - if (mShadowDrawable != null && mSectionsDistanceY > 0) { - mShadowDrawable.setBounds(mPinnedSection.view.getLeft(), - mPinnedSection.view.getBottom(), - mPinnedSection.view.getRight(), - mPinnedSection.view.getBottom() + mShadowHeight); - mShadowDrawable.draw(canvas); - } - - canvas.restore(); - } - } - - //-- touch handling methods - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - - final float x = ev.getX(); - final float y = ev.getY(); - final int action = ev.getAction(); - - if (action == MotionEvent.ACTION_DOWN - && mTouchTarget == null - && mPinnedSection != null - && isPinnedViewTouched(mPinnedSection.view, x, y)) { // create touch target - - // user touched pinned view - mTouchTarget = mPinnedSection.view; - mTouchPoint.x = x; - mTouchPoint.y = y; - - // copy down event for eventually be used later - mDownEvent = MotionEvent.obtain(ev); - } - - if (mTouchTarget != null) { - if (isPinnedViewTouched(mTouchTarget, x, y)) { // forward event to pinned view - mTouchTarget.dispatchTouchEvent(ev); - } - - if (action == MotionEvent.ACTION_UP) { // perform onClick on pinned view - super.dispatchTouchEvent(ev); - performPinnedItemClick(); - clearTouchTarget(); - - } else if (action == MotionEvent.ACTION_CANCEL) { // cancel - clearTouchTarget(); - - } else if (action == MotionEvent.ACTION_MOVE) { - if (Math.abs(y - mTouchPoint.y) > mTouchSlop) { - - // cancel sequence on touch target - MotionEvent event = MotionEvent.obtain(ev); - event.setAction(MotionEvent.ACTION_CANCEL); - mTouchTarget.dispatchTouchEvent(event); - event.recycle(); - - // provide correct sequence to super class for further handling - super.dispatchTouchEvent(mDownEvent); - super.dispatchTouchEvent(ev); - clearTouchTarget(); - - } - } - - return true; - } - - // call super if this was not our pinned view - return super.dispatchTouchEvent(ev); - } - - private boolean isPinnedViewTouched(View view, float x, float y) { - view.getHitRect(mTouchRect); - - // by taping top or bottom padding, the list performs on click on a border item. - // we don't add top padding here to keep behavior consistent. - mTouchRect.top += mTranslateY; - - mTouchRect.bottom += mTranslateY + getPaddingTop(); - mTouchRect.left += getPaddingLeft(); - mTouchRect.right -= getPaddingRight(); - return mTouchRect.contains((int)x, (int)y); - } - - private void clearTouchTarget() { - mTouchTarget = null; - if (mDownEvent != null) { - mDownEvent.recycle(); - mDownEvent = null; - } - } - - private boolean performPinnedItemClick() { - if (mPinnedSection == null) return false; - - OnItemClickListener listener = getOnItemClickListener(); - if (listener != null) { - View view = mPinnedSection.view; - playSoundEffect(SoundEffectConstants.CLICK); - if (view != null) { - view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - } - listener.onItemClick(this, view, mPinnedSection.position, mPinnedSection.id); - return true; - } - return false; - } - - public static boolean isItemViewTypePinned(ListAdapter adapter, int viewType) { - if (adapter instanceof HeaderViewListAdapter) { - adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter(); - } - return ((PinnedSectionListAdapter) adapter).isItemViewTypePinned(viewType); - } - -} diff --git a/libraries/pinned-section-listview/screen1.png b/libraries/pinned-section-listview/screen1.png deleted file mode 100644 index 9cca20109..000000000 Binary files a/libraries/pinned-section-listview/screen1.png and /dev/null differ diff --git a/libraries/pinned-section-listview/screen2.png b/libraries/pinned-section-listview/screen2.png deleted file mode 100644 index ad59f6f2f..000000000 Binary files a/libraries/pinned-section-listview/screen2.png and /dev/null differ diff --git a/libraries/pinned-section-listview/screen3.png b/libraries/pinned-section-listview/screen3.png deleted file mode 100644 index 0fd528fa9..000000000 Binary files a/libraries/pinned-section-listview/screen3.png and /dev/null differ -- cgit v1.2.3