[
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <Objective-C-extensions>\n      <file>\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Import\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Macro\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Typedef\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Enum\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Constant\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Global\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Struct\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"FunctionPredecl\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Function\" />\n      </file>\n      <class>\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Property\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Synthesize\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InitMethod\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"StaticMethod\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InstanceMethod\" />\n        <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"DeallocMethod\" />\n      </class>\n      <extensions>\n        <pair source=\"cpp\" header=\"h\" fileNamingConvention=\"NONE\" />\n        <pair source=\"c\" header=\"h\" fileNamingConvention=\"NONE\" />\n      </extensions>\n    </Objective-C-extensions>\n  </code_scheme>\n</component>"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <resourceExtensions />\n    <wildcardResourcePatterns>\n      <entry name=\"!?*.java\" />\n      <entry name=\"!?*.form\" />\n      <entry name=\"!?*.class\" />\n      <entry name=\"!?*.groovy\" />\n      <entry name=\"!?*.scala\" />\n      <entry name=\"!?*.flex\" />\n      <entry name=\"!?*.kt\" />\n      <entry name=\"!?*.clj\" />\n      <entry name=\"!?*.aj\" />\n    </wildcardResourcePatterns>\n    <annotationProcessing>\n      <profile default=\"true\" name=\"Default\" enabled=\"false\">\n        <processorPath useClasspath=\"true\" />\n      </profile>\n    </annotationProcessing>\n  </component>\n</project>"
  },
  {
    "path": ".idea/copyright/profiles_settings.xml",
    "content": "<component name=\"CopyrightManager\">\n  <settings default=\"\" />\n</component>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/samples\" />\n          </set>\n        </option>\n        <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/markdown-navigator/profiles_settings.xml",
    "content": "<component name=\"MarkdownNavigator.ProfileManager\">\n  <settings default=\"\" pdf-export=\"\" />\n</component>"
  },
  {
    "path": ".idea/markdown-navigator.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"MarkdownProjectSettings\">\n    <PreviewSettings splitEditorLayout=\"SPLIT\" splitEditorPreview=\"PREVIEW\" useGrayscaleRendering=\"false\" zoomFactor=\"1.0\" maxImageWidth=\"0\" showGitHubPageIfSynced=\"false\" allowBrowsingInPreview=\"false\" synchronizePreviewPosition=\"true\" highlightPreviewType=\"NONE\" highlightFadeOut=\"5\" highlightOnTyping=\"true\" synchronizeSourcePosition=\"true\">\n      <PanelProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.panel\" providerName=\"Default - Swing\" />\n      </PanelProvider>\n    </PreviewSettings>\n    <ParserSettings>\n      <PegdownExtensions>\n        <option name=\"ABBREVIATIONS\" value=\"false\" />\n        <option name=\"ANCHORLINKS\" value=\"true\" />\n        <option name=\"ATXHEADERSPACE\" value=\"true\" />\n        <option name=\"AUTOLINKS\" value=\"true\" />\n        <option name=\"DEFINITIONS\" value=\"false\" />\n        <option name=\"FENCED_CODE_BLOCKS\" value=\"true\" />\n        <option name=\"FOOTNOTES\" value=\"false\" />\n        <option name=\"HARDWRAPS\" value=\"false\" />\n        <option name=\"INSERTED\" value=\"false\" />\n        <option name=\"QUOTES\" value=\"false\" />\n        <option name=\"RELAXEDHRULES\" value=\"true\" />\n        <option name=\"SMARTS\" value=\"false\" />\n        <option name=\"STRIKETHROUGH\" value=\"true\" />\n        <option name=\"SUBSCRIPT\" value=\"false\" />\n        <option name=\"SUPERSCRIPT\" value=\"false\" />\n        <option name=\"SUPPRESS_HTML_BLOCKS\" value=\"false\" />\n        <option name=\"SUPPRESS_INLINE_HTML\" value=\"false\" />\n        <option name=\"TABLES\" value=\"true\" />\n        <option name=\"TASKLISTITEMS\" value=\"true\" />\n        <option name=\"TOC\" value=\"false\" />\n        <option name=\"WIKILINKS\" value=\"true\" />\n      </PegdownExtensions>\n      <ParserOptions>\n        <option name=\"COMMONMARK_LISTS\" value=\"false\" />\n        <option name=\"DUMMY\" value=\"false\" />\n        <option name=\"EMOJI_SHORTCUTS\" value=\"true\" />\n        <option name=\"FLEXMARK_FRONT_MATTER\" value=\"false\" />\n        <option name=\"GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA\" value=\"true\" />\n        <option name=\"GFM_TABLE_RENDERING\" value=\"true\" />\n        <option name=\"GITBOOK_URL_ENCODING\" value=\"false\" />\n        <option name=\"GITHUB_EMOJI_URL\" value=\"false\" />\n        <option name=\"GITHUB_LISTS\" value=\"true\" />\n        <option name=\"GITHUB_WIKI_LINKS\" value=\"true\" />\n        <option name=\"JEKYLL_FRONT_MATTER\" value=\"false\" />\n        <option name=\"SIM_TOC_BLANK_LINE_SPACER\" value=\"true\" />\n      </ParserOptions>\n    </ParserSettings>\n    <HtmlSettings headerTopEnabled=\"false\" headerBottomEnabled=\"false\" bodyTopEnabled=\"false\" bodyBottomEnabled=\"false\" embedUrlContent=\"false\" addPageHeader=\"true\">\n      <GeneratorProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.generator\" providerName=\"Default Swing HTML Generator\" />\n      </GeneratorProvider>\n      <headerTop />\n      <headerBottom />\n      <bodyTop />\n      <bodyBottom />\n    </HtmlSettings>\n    <CssSettings previewScheme=\"UI_SCHEME\" cssUri=\"\" isCssUriEnabled=\"false\" isCssTextEnabled=\"false\" isDynamicPageWidth=\"true\">\n      <StylesheetProvider>\n        <provider providerId=\"com.vladsch.idea.multimarkdown.editor.swing.html.css\" providerName=\"Default Swing Stylesheet\" />\n      </StylesheetProvider>\n      <ScriptProviders />\n      <cssText />\n    </CssSettings>\n    <HtmlExportSettings updateOnSave=\"false\" parentDir=\"$ProjectFileDir$\" targetDir=\"$ProjectFileDir$\" cssDir=\"\" scriptDir=\"\" plainHtml=\"false\" imageDir=\"\" copyLinkedImages=\"false\" imageUniquifyType=\"0\" targetExt=\"\" useTargetExt=\"false\" noCssNoScripts=\"false\" linkToExportedHtml=\"true\" exportOnSettingsChange=\"true\" regenerateOnProjectOpen=\"false\" />\n    <LinkMapSettings>\n      <textMaps />\n    </LinkMapSettings>\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"NullableNotNullManager\">\n    <option name=\"myDefaultNullable\" value=\"android.support.annotation.Nullable\" />\n    <option name=\"myDefaultNotNull\" value=\"android.support.annotation.NonNull\" />\n    <option name=\"myNullables\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.Nullable\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nullable\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.Nullable\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.Nullable\" />\n        </list>\n      </value>\n    </option>\n    <option name=\"myNotNulls\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.NotNull\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nonnull\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.NonNull\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.NonNull\" />\n        </list>\n      </value>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_8\" default=\"true\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/PopupList.iml\" filepath=\"$PROJECT_DIR$/PopupList.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/samples/samples.iml\" filepath=\"$PROJECT_DIR$/samples/samples.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "README.md",
    "content": "# PopupList\nIt can show a edit menu when you press a View by a long-press gesture.  \nThis utility class can bind a edit menu for ListView, GridView, or other View easily.  \n**Welcome star, fork**  \n## Screenshots\n![ScreenShot](https://github.com/shangmingchao/PopupList/blob/master/screenshots/screenshot_1.png)![ScreenShot](https://github.com/shangmingchao/PopupList/blob/master/screenshots/screenshot_2.png)<br />\n![ScreenShot](https://github.com/shangmingchao/PopupList/blob/master/screenshots/screenshot_3.png)![ScreenShot](https://github.com/shangmingchao/PopupList/blob/master/screenshots/screenshot_4.png)\n## How do I use PopupList?\nJust need a `.java` file and a little code.  \n```java\n    PopupList popupList = new PopupList(context);\n    popupList.bind(anchorView, popupMenuItemList, PopupListListener);\n```\n## Sample\n```java\n    PopupList popupList = new PopupList(this);\n    popupList.bind(lv_main, popupMenuItemList, new PopupList.PopupListListener() {\n        @Override\n        public boolean showPopupList(View adapterView, View contextView, int contextPosition) {\n            return true;\n        }\n        @Override\n        public void onPopupListClick(View contextView, int contextPosition, int position) {\n            Toast.makeText(MainActivity.this, contextPosition + \",\" + position, Toast.LENGTH_SHORT).show();\n        }\n    });\n```\n## Customization\nYou can get more information from the [Wiki](https://github.com/shangmingchao/PopupList/wiki/Configuration) page.  \n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.3'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Mar 13 11:51:38 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.4-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "library/PopupList.java",
    "content": "package com.frank.popuplist;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.content.res.Resources;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PixelFormat;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.graphics.drawable.GradientDrawable;\nimport android.graphics.drawable.StateListDrawable;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.ViewParent;\nimport android.widget.AbsListView;\nimport android.widget.AdapterView;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\nimport android.widget.PopupWindow;\nimport android.widget.TextView;\n\nimport java.util.List;\n\n/**\n * This utility class can show a edit menu easily\n */\npublic class PopupList {\n\n    public static final int DEFAULT_NORMAL_TEXT_COLOR = Color.WHITE;\n    public static final int DEFAULT_PRESSED_TEXT_COLOR = Color.WHITE;\n    public static final float DEFAULT_TEXT_SIZE_DP = 14;\n    public static final float DEFAULT_TEXT_PADDING_LEFT_DP = 10.0f;\n    public static final float DEFAULT_TEXT_PADDING_TOP_DP = 5.0f;\n    public static final float DEFAULT_TEXT_PADDING_RIGHT_DP = 10.0f;\n    public static final float DEFAULT_TEXT_PADDING_BOTTOM_DP = 5.0f;\n    public static final int DEFAULT_NORMAL_BACKGROUND_COLOR = 0xCC000000;\n    public static final int DEFAULT_PRESSED_BACKGROUND_COLOR = 0xE7777777;\n    public static final int DEFAULT_BACKGROUND_RADIUS_DP = 8;\n    public static final int DEFAULT_DIVIDER_COLOR = 0x9AFFFFFF;\n    public static final float DEFAULT_DIVIDER_WIDTH_DP = 0.5f;\n    public static final float DEFAULT_DIVIDER_HEIGHT_DP = 16.0f;\n\n    private Context mContext;\n    private PopupWindow mPopupWindow;\n    private View mAnchorView;\n    private View mAdapterView;\n    private View mContextView;\n    private View mIndicatorView;\n    private List<String> mPopupItemList;\n    private PopupListListener mPopupListListener;\n    private int mContextPosition;\n    private float mOffsetX;\n    private float mOffsetY;\n    private StateListDrawable mLeftItemBackground;\n    private StateListDrawable mRightItemBackground;\n    private StateListDrawable mCornerItemBackground;\n    private ColorStateList mTextColorStateList;\n    private GradientDrawable mCornerBackground;\n    private int mIndicatorWidth;\n    private int mIndicatorHeight;\n    private int mPopupWindowWidth;\n    private int mPopupWindowHeight;\n    private int mNormalTextColor;\n    private int mPressedTextColor;\n    private float mTextSize;\n    private int mTextPaddingLeft;\n    private int mTextPaddingTop;\n    private int mTextPaddingRight;\n    private int mTextPaddingBottom;\n    private int mNormalBackgroundColor;\n    private int mPressedBackgroundColor;\n    private int mBackgroundCornerRadius;\n    private int mDividerColor;\n    private int mDividerWidth;\n    private int mDividerHeight;\n\n    public PopupList(Context context) {\n        this.mContext = context;\n        this.mNormalTextColor = DEFAULT_NORMAL_TEXT_COLOR;\n        this.mPressedTextColor = DEFAULT_PRESSED_TEXT_COLOR;\n        this.mTextSize = dp2px(DEFAULT_TEXT_SIZE_DP);\n        this.mTextPaddingLeft = dp2px(DEFAULT_TEXT_PADDING_LEFT_DP);\n        this.mTextPaddingTop = dp2px(DEFAULT_TEXT_PADDING_TOP_DP);\n        this.mTextPaddingRight = dp2px(DEFAULT_TEXT_PADDING_RIGHT_DP);\n        this.mTextPaddingBottom = dp2px(DEFAULT_TEXT_PADDING_BOTTOM_DP);\n        this.mNormalBackgroundColor = DEFAULT_NORMAL_BACKGROUND_COLOR;\n        this.mPressedBackgroundColor = DEFAULT_PRESSED_BACKGROUND_COLOR;\n        this.mBackgroundCornerRadius = dp2px(DEFAULT_BACKGROUND_RADIUS_DP);\n        this.mDividerColor = DEFAULT_DIVIDER_COLOR;\n        this.mDividerWidth = dp2px(DEFAULT_DIVIDER_WIDTH_DP);\n        this.mDividerHeight = dp2px(DEFAULT_DIVIDER_HEIGHT_DP);\n        this.mIndicatorView = getDefaultIndicatorView(mContext);\n        refreshBackgroundOrRadiusStateList();\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    /**\n     * Popup a window when anchorView is clicked and held.\n     * That method will call {@link View#setOnTouchListener(View.OnTouchListener)} and\n     * {@link View#setOnLongClickListener(View.OnLongClickListener)}(or\n     * {@link AbsListView#setOnItemLongClickListener(AdapterView.OnItemLongClickListener)}\n     * if anchorView is a instance of AbsListView), so you can only use\n     * {@link PopupList#showPopupListWindow(View, int, float, float, List, PopupListListener)}\n     * if you called those method before.\n     *\n     * @param anchorView        the view on which to pin the popup window\n     * @param popupItemList     the list of the popup menu\n     * @param popupListListener the Listener\n     */\n    public void bind(View anchorView, List<String> popupItemList, PopupListListener popupListListener) {\n        this.mAnchorView = anchorView;\n        this.mPopupItemList = popupItemList;\n        this.mPopupListListener = popupListListener;\n        this.mPopupWindow = null;\n        mAnchorView.setOnTouchListener(new View.OnTouchListener() {\n            @Override\n            public boolean onTouch(View v, MotionEvent event) {\n                mOffsetX = event.getX();\n                mOffsetY = event.getY();\n                return false;\n            }\n        });\n        if (mAnchorView instanceof AbsListView) {\n            ((AbsListView) mAnchorView).setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {\n                @Override\n                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {\n                    if (mPopupListListener != null\n                            && !mPopupListListener.showPopupList(parent, view, position)) {\n                        return false;\n                    }\n                    mAdapterView = parent;\n                    mContextView = view;\n                    mContextPosition = position;\n                    showPopupListWindow(mOffsetX, mOffsetY);\n                    return true;\n                }\n            });\n        } else {\n            mAnchorView.setOnLongClickListener(new View.OnLongClickListener() {\n                @Override\n                public boolean onLongClick(View v) {\n                    if (mPopupListListener != null\n                            && !mPopupListListener.showPopupList(v, v, 0)) {\n                        return false;\n                    }\n                    mContextView = v;\n                    mContextPosition = 0;\n                    showPopupListWindow(mOffsetX, mOffsetY);\n                    return true;\n                }\n            });\n        }\n    }\n\n    /**\n     * show a popup window in a bubble style.\n     *\n     * @param anchorView        the view on which to pin the popup window\n     * @param contextPosition   context position\n     * @param rawX              the original raw X coordinate\n     * @param rawY              the original raw Y coordinate\n     * @param popupItemList     the list of the popup menu\n     * @param popupListListener the Listener\n     */\n    public void showPopupListWindow(View anchorView, int contextPosition, float rawX, float rawY,\n                                    List<String> popupItemList, PopupListListener popupListListener) {\n        mAnchorView = anchorView;\n        mContextPosition = contextPosition;\n        mPopupItemList = popupItemList;\n        mPopupListListener = popupListListener;\n        mPopupWindow = null;\n        mContextView = anchorView;\n        if (mPopupListListener != null\n                && !mPopupListListener.showPopupList(mContextView, mContextView, contextPosition)) {\n            return;\n        }\n        int[] location = new int[2];\n        mAnchorView.getLocationOnScreen(location);\n        showPopupListWindow(rawX - location[0], rawY - location[1]);\n    }\n\n    private void showPopupListWindow(float offsetX, float offsetY) {\n        if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {\n            return;\n        }\n        if (mPopupWindow == null || mPopupListListener instanceof AdapterPopupListListener) {\n            LinearLayout contentView = new LinearLayout(mContext);\n            contentView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));\n            contentView.setOrientation(LinearLayout.VERTICAL);\n            LinearLayout popupListContainer = new LinearLayout(mContext);\n            popupListContainer.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));\n            popupListContainer.setOrientation(LinearLayout.HORIZONTAL);\n            popupListContainer.setBackgroundDrawable(mCornerBackground);\n            contentView.addView(popupListContainer);\n            if (mIndicatorView != null) {\n                LinearLayout.LayoutParams layoutParams;\n                if (mIndicatorView.getLayoutParams() == null) {\n                    layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);\n                } else {\n                    layoutParams = (LinearLayout.LayoutParams) mIndicatorView.getLayoutParams();\n                }\n                layoutParams.gravity = Gravity.CENTER;\n                mIndicatorView.setLayoutParams(layoutParams);\n                ViewParent viewParent = mIndicatorView.getParent();\n                if (viewParent instanceof ViewGroup) {\n                    ((ViewGroup) viewParent).removeView(mIndicatorView);\n                }\n                contentView.addView(mIndicatorView);\n            }\n            for (int i = 0; i < mPopupItemList.size(); i++) {\n                TextView textView = new TextView(mContext);\n                textView.setTextColor(mTextColorStateList);\n                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);\n                textView.setPadding(mTextPaddingLeft, mTextPaddingTop, mTextPaddingRight, mTextPaddingBottom);\n                textView.setClickable(true);\n                final int finalI = i;\n                textView.setOnClickListener(new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        if (mPopupListListener != null) {\n                            mPopupListListener.onPopupListClick(mContextView, mContextPosition, finalI);\n                            hidePopupListWindow();\n                        }\n                    }\n                });\n                if (mPopupListListener instanceof AdapterPopupListListener) {\n                    AdapterPopupListListener adapterPopupListListener = (AdapterPopupListListener) mPopupListListener;\n                    textView.setText(adapterPopupListListener.formatText(mAdapterView, mContextView, mContextPosition, i, mPopupItemList.get(i)));\n                } else {\n                    textView.setText(mPopupItemList.get(i));\n                }\n                if (mPopupItemList.size() > 1 && i == 0) {\n                    textView.setBackgroundDrawable(mLeftItemBackground);\n                } else if (mPopupItemList.size() > 1 && i == mPopupItemList.size() - 1) {\n                    textView.setBackgroundDrawable(mRightItemBackground);\n                } else if (mPopupItemList.size() == 1) {\n                    textView.setBackgroundDrawable(mCornerItemBackground);\n                } else {\n                    textView.setBackgroundDrawable(getCenterItemBackground());\n                }\n                popupListContainer.addView(textView);\n                if (mPopupItemList.size() > 1 && i != mPopupItemList.size() - 1) {\n                    View divider = new View(mContext);\n                    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(mDividerWidth, mDividerHeight);\n                    layoutParams.gravity = Gravity.CENTER;\n                    divider.setLayoutParams(layoutParams);\n                    divider.setBackgroundColor(mDividerColor);\n                    popupListContainer.addView(divider);\n                }\n            }\n            if (mPopupWindowWidth == 0) {\n                mPopupWindowWidth = getViewWidth(popupListContainer);\n            }\n            if (mIndicatorView != null && mIndicatorWidth == 0) {\n                if (mIndicatorView.getLayoutParams().width > 0) {\n                    mIndicatorWidth = mIndicatorView.getLayoutParams().width;\n                } else {\n                    mIndicatorWidth = getViewWidth(mIndicatorView);\n                }\n            }\n            if (mIndicatorView != null && mIndicatorHeight == 0) {\n                if (mIndicatorView.getLayoutParams().height > 0) {\n                    mIndicatorHeight = mIndicatorView.getLayoutParams().height;\n                } else {\n                    mIndicatorHeight = getViewHeight(mIndicatorView);\n                }\n            }\n            if (mPopupWindowHeight == 0) {\n                mPopupWindowHeight = getViewHeight(popupListContainer) + mIndicatorHeight;\n            }\n            mPopupWindow = new PopupWindow(contentView, mPopupWindowWidth, mPopupWindowHeight, true);\n            mPopupWindow.setTouchable(true);\n            mPopupWindow.setBackgroundDrawable(new BitmapDrawable());\n        }\n        int[] location = new int[2];\n        mAnchorView.getLocationOnScreen(location);\n        if (mIndicatorView != null) {\n            float leftTranslationLimit = mIndicatorWidth / 2f + mBackgroundCornerRadius - mPopupWindowWidth / 2f;\n            float rightTranslationLimit = mPopupWindowWidth / 2f - mIndicatorWidth / 2f - mBackgroundCornerRadius;\n            float maxWidth = mContext.getResources().getDisplayMetrics().widthPixels;\n            if (location[0] + offsetX < mPopupWindowWidth / 2f) {\n                mIndicatorView.setTranslationX(Math.max(location[0] + offsetX - mPopupWindowWidth / 2f, leftTranslationLimit));\n            } else if (location[0] + offsetX + mPopupWindowWidth / 2f > maxWidth) {\n                mIndicatorView.setTranslationX(Math.min(location[0] + offsetX + mPopupWindowWidth / 2f - maxWidth, rightTranslationLimit));\n            } else {\n                mIndicatorView.setTranslationX(0);\n            }\n        }\n        if (!mPopupWindow.isShowing()) {\n            int x = (int) (location[0] + offsetX - mPopupWindowWidth / 2f + 0.5f);\n            int y = (int) (location[1] + offsetY - mPopupWindowHeight + 0.5f);\n            mPopupWindow.showAtLocation(mAnchorView, Gravity.NO_GRAVITY, x, y);\n        }\n    }\n\n    private void refreshBackgroundOrRadiusStateList() {\n        // left\n        GradientDrawable leftItemPressedDrawable = new GradientDrawable();\n        leftItemPressedDrawable.setColor(mPressedBackgroundColor);\n        leftItemPressedDrawable.setCornerRadii(new float[]{\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0,\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius});\n        GradientDrawable leftItemNormalDrawable = new GradientDrawable();\n        leftItemNormalDrawable.setColor(Color.TRANSPARENT);\n        leftItemNormalDrawable.setCornerRadii(new float[]{\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0,\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius});\n        mLeftItemBackground = new StateListDrawable();\n        mLeftItemBackground.addState(new int[]{android.R.attr.state_pressed}, leftItemPressedDrawable);\n        mLeftItemBackground.addState(new int[]{}, leftItemNormalDrawable);\n        // right\n        GradientDrawable rightItemPressedDrawable = new GradientDrawable();\n        rightItemPressedDrawable.setColor(mPressedBackgroundColor);\n        rightItemPressedDrawable.setCornerRadii(new float[]{\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0});\n        GradientDrawable rightItemNormalDrawable = new GradientDrawable();\n        rightItemNormalDrawable.setColor(Color.TRANSPARENT);\n        rightItemNormalDrawable.setCornerRadii(new float[]{\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0});\n        mRightItemBackground = new StateListDrawable();\n        mRightItemBackground.addState(new int[]{android.R.attr.state_pressed}, rightItemPressedDrawable);\n        mRightItemBackground.addState(new int[]{}, rightItemNormalDrawable);\n        // corner\n        GradientDrawable cornerItemPressedDrawable = new GradientDrawable();\n        cornerItemPressedDrawable.setColor(mPressedBackgroundColor);\n        cornerItemPressedDrawable.setCornerRadius(mBackgroundCornerRadius);\n        GradientDrawable cornerItemNormalDrawable = new GradientDrawable();\n        cornerItemNormalDrawable.setColor(Color.TRANSPARENT);\n        cornerItemNormalDrawable.setCornerRadius(mBackgroundCornerRadius);\n        mCornerItemBackground = new StateListDrawable();\n        mCornerItemBackground.addState(new int[]{android.R.attr.state_pressed}, cornerItemPressedDrawable);\n        mCornerItemBackground.addState(new int[]{}, cornerItemNormalDrawable);\n        mCornerBackground = new GradientDrawable();\n        mCornerBackground.setColor(mNormalBackgroundColor);\n        mCornerBackground.setCornerRadius(mBackgroundCornerRadius);\n    }\n\n    private StateListDrawable getCenterItemBackground() {\n        StateListDrawable centerItemBackground = new StateListDrawable();\n        GradientDrawable centerItemPressedDrawable = new GradientDrawable();\n        centerItemPressedDrawable.setColor(mPressedBackgroundColor);\n        GradientDrawable centerItemNormalDrawable = new GradientDrawable();\n        centerItemNormalDrawable.setColor(Color.TRANSPARENT);\n        centerItemBackground.addState(new int[]{android.R.attr.state_pressed}, centerItemPressedDrawable);\n        centerItemBackground.addState(new int[]{}, centerItemNormalDrawable);\n        return centerItemBackground;\n    }\n\n    private void refreshTextColorStateList(int pressedTextColor, int normalTextColor) {\n        int[][] states = new int[2][];\n        states[0] = new int[]{android.R.attr.state_pressed};\n        states[1] = new int[]{};\n        int[] colors = new int[]{pressedTextColor, normalTextColor};\n        mTextColorStateList = new ColorStateList(states, colors);\n    }\n\n    public void hidePopupListWindow() {\n        if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {\n            return;\n        }\n        if (mPopupWindow != null && mPopupWindow.isShowing()) {\n            mPopupWindow.dismiss();\n        }\n    }\n\n    public View getIndicatorView() {\n        return mIndicatorView;\n    }\n\n    public View getDefaultIndicatorView(Context context) {\n        return getTriangleIndicatorView(context, dp2px(16), dp2px(8), DEFAULT_NORMAL_BACKGROUND_COLOR);\n    }\n\n    public View getTriangleIndicatorView(Context context, final float widthPixel, final float heightPixel,\n                                         final int color) {\n        ImageView indicator = new ImageView(context);\n        Drawable drawable = new Drawable() {\n            @Override\n            public void draw(Canvas canvas) {\n                Path path = new Path();\n                Paint paint = new Paint();\n                paint.setColor(color);\n                paint.setStyle(Paint.Style.FILL);\n                path.moveTo(0f, 0f);\n                path.lineTo(widthPixel, 0f);\n                path.lineTo(widthPixel / 2, heightPixel);\n                path.close();\n                canvas.drawPath(path, paint);\n            }\n\n            @Override\n            public void setAlpha(int alpha) {\n\n            }\n\n            @Override\n            public void setColorFilter(ColorFilter colorFilter) {\n\n            }\n\n            @Override\n            public int getOpacity() {\n                return PixelFormat.TRANSLUCENT;\n            }\n\n            @Override\n            public int getIntrinsicWidth() {\n                return (int) widthPixel;\n            }\n\n            @Override\n            public int getIntrinsicHeight() {\n                return (int) heightPixel;\n            }\n        };\n        indicator.setImageDrawable(drawable);\n        return indicator;\n    }\n\n    public void setIndicatorView(View indicatorView) {\n        this.mIndicatorView = indicatorView;\n    }\n\n    public void setIndicatorSize(int widthPixel, int heightPixel) {\n        this.mIndicatorWidth = widthPixel;\n        this.mIndicatorHeight = heightPixel;\n        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(mIndicatorWidth, mIndicatorHeight);\n        layoutParams.gravity = Gravity.CENTER;\n        if (mIndicatorView != null) {\n            mIndicatorView.setLayoutParams(layoutParams);\n        }\n    }\n\n    public int getNormalTextColor() {\n        return mNormalTextColor;\n    }\n\n    public void setNormalTextColor(int normalTextColor) {\n        this.mNormalTextColor = normalTextColor;\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    public int getPressedTextColor() {\n        return mPressedTextColor;\n    }\n\n    public void setPressedTextColor(int pressedTextColor) {\n        this.mPressedTextColor = pressedTextColor;\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    public float getTextSize() {\n        return mTextSize;\n    }\n\n    public void setTextSize(float textSizePixel) {\n        this.mTextSize = textSizePixel;\n    }\n\n    public int getTextPaddingLeft() {\n        return mTextPaddingLeft;\n    }\n\n    public void setTextPaddingLeft(int textPaddingLeft) {\n        this.mTextPaddingLeft = textPaddingLeft;\n    }\n\n    public int getTextPaddingTop() {\n        return mTextPaddingTop;\n    }\n\n    public void setTextPaddingTop(int textPaddingTop) {\n        this.mTextPaddingTop = textPaddingTop;\n    }\n\n    public int getTextPaddingRight() {\n        return mTextPaddingRight;\n    }\n\n    public void setTextPaddingRight(int textPaddingRight) {\n        this.mTextPaddingRight = textPaddingRight;\n    }\n\n    public int getTextPaddingBottom() {\n        return mTextPaddingBottom;\n    }\n\n    public void setTextPaddingBottom(int textPaddingBottom) {\n        this.mTextPaddingBottom = textPaddingBottom;\n    }\n\n    /**\n     * @param left   the left padding in pixels\n     * @param top    the top padding in pixels\n     * @param right  the right padding in pixels\n     * @param bottom the bottom padding in pixels\n     */\n    public void setTextPadding(int left, int top, int right, int bottom) {\n        this.mTextPaddingLeft = left;\n        this.mTextPaddingTop = top;\n        this.mTextPaddingRight = right;\n        this.mTextPaddingBottom = bottom;\n    }\n\n    public int getNormalBackgroundColor() {\n        return mNormalBackgroundColor;\n    }\n\n    public void setNormalBackgroundColor(int normalBackgroundColor) {\n        this.mNormalBackgroundColor = normalBackgroundColor;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getPressedBackgroundColor() {\n        return mPressedBackgroundColor;\n    }\n\n    public void setPressedBackgroundColor(int pressedBackgroundColor) {\n        this.mPressedBackgroundColor = pressedBackgroundColor;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getBackgroundCornerRadius() {\n        return mBackgroundCornerRadius;\n    }\n\n    public void setBackgroundCornerRadius(int backgroundCornerRadiusPixel) {\n        this.mBackgroundCornerRadius = backgroundCornerRadiusPixel;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getDividerColor() {\n        return mDividerColor;\n    }\n\n    public void setDividerColor(int dividerColor) {\n        this.mDividerColor = dividerColor;\n    }\n\n    public int getDividerWidth() {\n        return mDividerWidth;\n    }\n\n    public void setDividerWidth(int dividerWidthPixel) {\n        this.mDividerWidth = dividerWidthPixel;\n    }\n\n    public int getDividerHeight() {\n        return mDividerHeight;\n    }\n\n    public void setDividerHeight(int dividerHeightPixel) {\n        this.mDividerHeight = dividerHeightPixel;\n    }\n\n    public Resources getResources() {\n        if (mContext == null) {\n            return Resources.getSystem();\n        } else {\n            return mContext.getResources();\n        }\n    }\n\n    private int getViewWidth(View view) {\n        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));\n        return view.getMeasuredWidth();\n    }\n\n    private int getViewHeight(View view) {\n        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));\n        return view.getMeasuredHeight();\n    }\n\n    public int dp2px(float value) {\n        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,\n                value, getResources().getDisplayMetrics());\n    }\n\n    public int sp2px(float value) {\n        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,\n                value, getResources().getDisplayMetrics());\n    }\n\n    public interface PopupListListener {\n\n        /**\n         * Whether the PopupList should be bound to the special view\n         *\n         * @param adapterView     The context view(The AbsListView where the click happened or normal view).\n         * @param contextView     The view within the AbsListView that was clicked or normal view\n         * @param contextPosition The position of the view in the list\n         * @return true if the view should bind the PopupList, false otherwise\n         */\n        boolean showPopupList(View adapterView, View contextView, int contextPosition);\n\n        /**\n         * The callback to be invoked with an item in this PopupList has\n         * been clicked\n         *\n         * @param contextView     The context view(The AbsListView where the click happened or normal view).\n         * @param contextPosition The position of the view in the list\n         * @param position        The position of the view in the PopupList\n         */\n        void onPopupListClick(View contextView, int contextPosition, int position);\n    }\n\n    public interface AdapterPopupListListener extends PopupListListener {\n        String formatText(View adapterView, View contextView, int contextPosition, int position, String text);\n    }\n\n}\n\n"
  },
  {
    "path": "samples/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "samples/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n\n    defaultConfig {\n        applicationId \"com.frank.popuplist\"\n        minSdkVersion 15\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.1'\n    testImplementation 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "samples/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:\\Users\\frank\\AppData\\Local\\Android\\Sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "samples/src/androidTest/java/com/frank/popuplist/ApplicationTest.java",
    "content": "package com.frank.popuplist;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "samples/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.frank.popuplist\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"com.frank.sample.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\"com.frank.sample.SecondaryActivity\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "samples/src/main/java/com/frank/popuplist/PopupList.java",
    "content": "package com.frank.popuplist;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.content.res.Resources;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PixelFormat;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.graphics.drawable.GradientDrawable;\nimport android.graphics.drawable.StateListDrawable;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.ViewParent;\nimport android.widget.AbsListView;\nimport android.widget.AdapterView;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\nimport android.widget.PopupWindow;\nimport android.widget.TextView;\n\nimport java.util.List;\n\n/**\n * This utility class can show a edit menu easily\n */\npublic class PopupList {\n\n    public static final int DEFAULT_NORMAL_TEXT_COLOR = Color.WHITE;\n    public static final int DEFAULT_PRESSED_TEXT_COLOR = Color.WHITE;\n    public static final float DEFAULT_TEXT_SIZE_DP = 14;\n    public static final float DEFAULT_TEXT_PADDING_LEFT_DP = 10.0f;\n    public static final float DEFAULT_TEXT_PADDING_TOP_DP = 5.0f;\n    public static final float DEFAULT_TEXT_PADDING_RIGHT_DP = 10.0f;\n    public static final float DEFAULT_TEXT_PADDING_BOTTOM_DP = 5.0f;\n    public static final int DEFAULT_NORMAL_BACKGROUND_COLOR = 0xCC000000;\n    public static final int DEFAULT_PRESSED_BACKGROUND_COLOR = 0xE7777777;\n    public static final int DEFAULT_BACKGROUND_RADIUS_DP = 8;\n    public static final int DEFAULT_DIVIDER_COLOR = 0x9AFFFFFF;\n    public static final float DEFAULT_DIVIDER_WIDTH_DP = 0.5f;\n    public static final float DEFAULT_DIVIDER_HEIGHT_DP = 16.0f;\n\n    private Context mContext;\n    private PopupWindow mPopupWindow;\n    private View mAnchorView;\n    private View mAdapterView;\n    private View mContextView;\n    private View mIndicatorView;\n    private List<String> mPopupItemList;\n    private PopupListListener mPopupListListener;\n    private int mContextPosition;\n    private float mOffsetX;\n    private float mOffsetY;\n    private StateListDrawable mLeftItemBackground;\n    private StateListDrawable mRightItemBackground;\n    private StateListDrawable mCornerItemBackground;\n    private ColorStateList mTextColorStateList;\n    private GradientDrawable mCornerBackground;\n    private int mIndicatorWidth;\n    private int mIndicatorHeight;\n    private int mPopupWindowWidth;\n    private int mPopupWindowHeight;\n    private int mNormalTextColor;\n    private int mPressedTextColor;\n    private float mTextSize;\n    private int mTextPaddingLeft;\n    private int mTextPaddingTop;\n    private int mTextPaddingRight;\n    private int mTextPaddingBottom;\n    private int mNormalBackgroundColor;\n    private int mPressedBackgroundColor;\n    private int mBackgroundCornerRadius;\n    private int mDividerColor;\n    private int mDividerWidth;\n    private int mDividerHeight;\n\n    public PopupList(Context context) {\n        this.mContext = context;\n        this.mNormalTextColor = DEFAULT_NORMAL_TEXT_COLOR;\n        this.mPressedTextColor = DEFAULT_PRESSED_TEXT_COLOR;\n        this.mTextSize = dp2px(DEFAULT_TEXT_SIZE_DP);\n        this.mTextPaddingLeft = dp2px(DEFAULT_TEXT_PADDING_LEFT_DP);\n        this.mTextPaddingTop = dp2px(DEFAULT_TEXT_PADDING_TOP_DP);\n        this.mTextPaddingRight = dp2px(DEFAULT_TEXT_PADDING_RIGHT_DP);\n        this.mTextPaddingBottom = dp2px(DEFAULT_TEXT_PADDING_BOTTOM_DP);\n        this.mNormalBackgroundColor = DEFAULT_NORMAL_BACKGROUND_COLOR;\n        this.mPressedBackgroundColor = DEFAULT_PRESSED_BACKGROUND_COLOR;\n        this.mBackgroundCornerRadius = dp2px(DEFAULT_BACKGROUND_RADIUS_DP);\n        this.mDividerColor = DEFAULT_DIVIDER_COLOR;\n        this.mDividerWidth = dp2px(DEFAULT_DIVIDER_WIDTH_DP);\n        this.mDividerHeight = dp2px(DEFAULT_DIVIDER_HEIGHT_DP);\n        this.mIndicatorView = getDefaultIndicatorView(mContext);\n        refreshBackgroundOrRadiusStateList();\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    /**\n     * Popup a window when anchorView is clicked and held.\n     * That method will call {@link View#setOnTouchListener(View.OnTouchListener)} and\n     * {@link View#setOnLongClickListener(View.OnLongClickListener)}(or\n     * {@link AbsListView#setOnItemLongClickListener(AdapterView.OnItemLongClickListener)}\n     * if anchorView is a instance of AbsListView), so you can only use\n     * {@link PopupList#showPopupListWindow(View, int, float, float, List, PopupListListener)}\n     * if you called those method before.\n     *\n     * @param anchorView        the view on which to pin the popup window\n     * @param popupItemList     the list of the popup menu\n     * @param popupListListener the Listener\n     */\n    public void bind(View anchorView, List<String> popupItemList, PopupListListener popupListListener) {\n        this.mAnchorView = anchorView;\n        this.mPopupItemList = popupItemList;\n        this.mPopupListListener = popupListListener;\n        this.mPopupWindow = null;\n        mAnchorView.setOnTouchListener(new View.OnTouchListener() {\n            @Override\n            public boolean onTouch(View v, MotionEvent event) {\n                mOffsetX = event.getX();\n                mOffsetY = event.getY();\n                return false;\n            }\n        });\n        if (mAnchorView instanceof AbsListView) {\n            ((AbsListView) mAnchorView).setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {\n                @Override\n                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {\n                    if (mPopupListListener != null\n                            && !mPopupListListener.showPopupList(parent, view, position)) {\n                        return false;\n                    }\n                    mAdapterView = parent;\n                    mContextView = view;\n                    mContextPosition = position;\n                    showPopupListWindow(mOffsetX, mOffsetY);\n                    return true;\n                }\n            });\n        } else {\n            mAnchorView.setOnLongClickListener(new View.OnLongClickListener() {\n                @Override\n                public boolean onLongClick(View v) {\n                    if (mPopupListListener != null\n                            && !mPopupListListener.showPopupList(v, v, 0)) {\n                        return false;\n                    }\n                    mContextView = v;\n                    mContextPosition = 0;\n                    showPopupListWindow(mOffsetX, mOffsetY);\n                    return true;\n                }\n            });\n        }\n    }\n\n    /**\n     * show a popup window in a bubble style.\n     *\n     * @param anchorView        the view on which to pin the popup window\n     * @param contextPosition   context position\n     * @param rawX              the original raw X coordinate\n     * @param rawY              the original raw Y coordinate\n     * @param popupItemList     the list of the popup menu\n     * @param popupListListener the Listener\n     */\n    public void showPopupListWindow(View anchorView, int contextPosition, float rawX, float rawY,\n                                    List<String> popupItemList, PopupListListener popupListListener) {\n        mAnchorView = anchorView;\n        mContextPosition = contextPosition;\n        mPopupItemList = popupItemList;\n        mPopupListListener = popupListListener;\n        mPopupWindow = null;\n        mContextView = anchorView;\n        if (mPopupListListener != null\n                && !mPopupListListener.showPopupList(mContextView, mContextView, contextPosition)) {\n            return;\n        }\n        int[] location = new int[2];\n        mAnchorView.getLocationOnScreen(location);\n        showPopupListWindow(rawX - location[0], rawY - location[1]);\n    }\n\n    private void showPopupListWindow(float offsetX, float offsetY) {\n        if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {\n            return;\n        }\n        if (mPopupWindow == null || mPopupListListener instanceof AdapterPopupListListener) {\n            LinearLayout contentView = new LinearLayout(mContext);\n            contentView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));\n            contentView.setOrientation(LinearLayout.VERTICAL);\n            LinearLayout popupListContainer = new LinearLayout(mContext);\n            popupListContainer.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));\n            popupListContainer.setOrientation(LinearLayout.HORIZONTAL);\n            popupListContainer.setBackgroundDrawable(mCornerBackground);\n            contentView.addView(popupListContainer);\n            if (mIndicatorView != null) {\n                LinearLayout.LayoutParams layoutParams;\n                if (mIndicatorView.getLayoutParams() == null) {\n                    layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);\n                } else {\n                    layoutParams = (LinearLayout.LayoutParams) mIndicatorView.getLayoutParams();\n                }\n                layoutParams.gravity = Gravity.CENTER;\n                mIndicatorView.setLayoutParams(layoutParams);\n                ViewParent viewParent = mIndicatorView.getParent();\n                if (viewParent instanceof ViewGroup) {\n                    ((ViewGroup) viewParent).removeView(mIndicatorView);\n                }\n                contentView.addView(mIndicatorView);\n            }\n            for (int i = 0; i < mPopupItemList.size(); i++) {\n                TextView textView = new TextView(mContext);\n                textView.setTextColor(mTextColorStateList);\n                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);\n                textView.setPadding(mTextPaddingLeft, mTextPaddingTop, mTextPaddingRight, mTextPaddingBottom);\n                textView.setClickable(true);\n                final int finalI = i;\n                textView.setOnClickListener(new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        if (mPopupListListener != null) {\n                            mPopupListListener.onPopupListClick(mContextView, mContextPosition, finalI);\n                            hidePopupListWindow();\n                        }\n                    }\n                });\n                if (mPopupListListener instanceof AdapterPopupListListener) {\n                    AdapterPopupListListener adapterPopupListListener = (AdapterPopupListListener) mPopupListListener;\n                    textView.setText(adapterPopupListListener.formatText(mAdapterView, mContextView, mContextPosition, i, mPopupItemList.get(i)));\n                } else {\n                    textView.setText(mPopupItemList.get(i));\n                }\n                if (mPopupItemList.size() > 1 && i == 0) {\n                    textView.setBackgroundDrawable(mLeftItemBackground);\n                } else if (mPopupItemList.size() > 1 && i == mPopupItemList.size() - 1) {\n                    textView.setBackgroundDrawable(mRightItemBackground);\n                } else if (mPopupItemList.size() == 1) {\n                    textView.setBackgroundDrawable(mCornerItemBackground);\n                } else {\n                    textView.setBackgroundDrawable(getCenterItemBackground());\n                }\n                popupListContainer.addView(textView);\n                if (mPopupItemList.size() > 1 && i != mPopupItemList.size() - 1) {\n                    View divider = new View(mContext);\n                    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(mDividerWidth, mDividerHeight);\n                    layoutParams.gravity = Gravity.CENTER;\n                    divider.setLayoutParams(layoutParams);\n                    divider.setBackgroundColor(mDividerColor);\n                    popupListContainer.addView(divider);\n                }\n            }\n            if (mPopupWindowWidth == 0) {\n                mPopupWindowWidth = getViewWidth(popupListContainer);\n            }\n            if (mIndicatorView != null && mIndicatorWidth == 0) {\n                if (mIndicatorView.getLayoutParams().width > 0) {\n                    mIndicatorWidth = mIndicatorView.getLayoutParams().width;\n                } else {\n                    mIndicatorWidth = getViewWidth(mIndicatorView);\n                }\n            }\n            if (mIndicatorView != null && mIndicatorHeight == 0) {\n                if (mIndicatorView.getLayoutParams().height > 0) {\n                    mIndicatorHeight = mIndicatorView.getLayoutParams().height;\n                } else {\n                    mIndicatorHeight = getViewHeight(mIndicatorView);\n                }\n            }\n            if (mPopupWindowHeight == 0) {\n                mPopupWindowHeight = getViewHeight(popupListContainer) + mIndicatorHeight;\n            }\n            mPopupWindow = new PopupWindow(contentView, mPopupWindowWidth, mPopupWindowHeight, true);\n            mPopupWindow.setTouchable(true);\n            mPopupWindow.setBackgroundDrawable(new BitmapDrawable());\n        }\n        int[] location = new int[2];\n        mAnchorView.getLocationOnScreen(location);\n        if (mIndicatorView != null) {\n            float leftTranslationLimit = mIndicatorWidth / 2f + mBackgroundCornerRadius - mPopupWindowWidth / 2f;\n            float rightTranslationLimit = mPopupWindowWidth / 2f - mIndicatorWidth / 2f - mBackgroundCornerRadius;\n            float maxWidth = mContext.getResources().getDisplayMetrics().widthPixels;\n            if (location[0] + offsetX < mPopupWindowWidth / 2f) {\n                mIndicatorView.setTranslationX(Math.max(location[0] + offsetX - mPopupWindowWidth / 2f, leftTranslationLimit));\n            } else if (location[0] + offsetX + mPopupWindowWidth / 2f > maxWidth) {\n                mIndicatorView.setTranslationX(Math.min(location[0] + offsetX + mPopupWindowWidth / 2f - maxWidth, rightTranslationLimit));\n            } else {\n                mIndicatorView.setTranslationX(0);\n            }\n        }\n        if (!mPopupWindow.isShowing()) {\n            int x = (int) (location[0] + offsetX - mPopupWindowWidth / 2f + 0.5f);\n            int y = (int) (location[1] + offsetY - mPopupWindowHeight + 0.5f);\n            mPopupWindow.showAtLocation(mAnchorView, Gravity.NO_GRAVITY, x, y);\n        }\n    }\n\n    private void refreshBackgroundOrRadiusStateList() {\n        // left\n        GradientDrawable leftItemPressedDrawable = new GradientDrawable();\n        leftItemPressedDrawable.setColor(mPressedBackgroundColor);\n        leftItemPressedDrawable.setCornerRadii(new float[]{\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0,\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius});\n        GradientDrawable leftItemNormalDrawable = new GradientDrawable();\n        leftItemNormalDrawable.setColor(Color.TRANSPARENT);\n        leftItemNormalDrawable.setCornerRadii(new float[]{\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0,\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius});\n        mLeftItemBackground = new StateListDrawable();\n        mLeftItemBackground.addState(new int[]{android.R.attr.state_pressed}, leftItemPressedDrawable);\n        mLeftItemBackground.addState(new int[]{}, leftItemNormalDrawable);\n        // right\n        GradientDrawable rightItemPressedDrawable = new GradientDrawable();\n        rightItemPressedDrawable.setColor(mPressedBackgroundColor);\n        rightItemPressedDrawable.setCornerRadii(new float[]{\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0});\n        GradientDrawable rightItemNormalDrawable = new GradientDrawable();\n        rightItemNormalDrawable.setColor(Color.TRANSPARENT);\n        rightItemNormalDrawable.setCornerRadii(new float[]{\n                0, 0,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                mBackgroundCornerRadius, mBackgroundCornerRadius,\n                0, 0});\n        mRightItemBackground = new StateListDrawable();\n        mRightItemBackground.addState(new int[]{android.R.attr.state_pressed}, rightItemPressedDrawable);\n        mRightItemBackground.addState(new int[]{}, rightItemNormalDrawable);\n        // corner\n        GradientDrawable cornerItemPressedDrawable = new GradientDrawable();\n        cornerItemPressedDrawable.setColor(mPressedBackgroundColor);\n        cornerItemPressedDrawable.setCornerRadius(mBackgroundCornerRadius);\n        GradientDrawable cornerItemNormalDrawable = new GradientDrawable();\n        cornerItemNormalDrawable.setColor(Color.TRANSPARENT);\n        cornerItemNormalDrawable.setCornerRadius(mBackgroundCornerRadius);\n        mCornerItemBackground = new StateListDrawable();\n        mCornerItemBackground.addState(new int[]{android.R.attr.state_pressed}, cornerItemPressedDrawable);\n        mCornerItemBackground.addState(new int[]{}, cornerItemNormalDrawable);\n        mCornerBackground = new GradientDrawable();\n        mCornerBackground.setColor(mNormalBackgroundColor);\n        mCornerBackground.setCornerRadius(mBackgroundCornerRadius);\n    }\n\n    private StateListDrawable getCenterItemBackground() {\n        StateListDrawable centerItemBackground = new StateListDrawable();\n        GradientDrawable centerItemPressedDrawable = new GradientDrawable();\n        centerItemPressedDrawable.setColor(mPressedBackgroundColor);\n        GradientDrawable centerItemNormalDrawable = new GradientDrawable();\n        centerItemNormalDrawable.setColor(Color.TRANSPARENT);\n        centerItemBackground.addState(new int[]{android.R.attr.state_pressed}, centerItemPressedDrawable);\n        centerItemBackground.addState(new int[]{}, centerItemNormalDrawable);\n        return centerItemBackground;\n    }\n\n    private void refreshTextColorStateList(int pressedTextColor, int normalTextColor) {\n        int[][] states = new int[2][];\n        states[0] = new int[]{android.R.attr.state_pressed};\n        states[1] = new int[]{};\n        int[] colors = new int[]{pressedTextColor, normalTextColor};\n        mTextColorStateList = new ColorStateList(states, colors);\n    }\n\n    public void hidePopupListWindow() {\n        if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {\n            return;\n        }\n        if (mPopupWindow != null && mPopupWindow.isShowing()) {\n            mPopupWindow.dismiss();\n        }\n    }\n\n    public View getIndicatorView() {\n        return mIndicatorView;\n    }\n\n    public View getDefaultIndicatorView(Context context) {\n        return getTriangleIndicatorView(context, dp2px(16), dp2px(8), DEFAULT_NORMAL_BACKGROUND_COLOR);\n    }\n\n    public View getTriangleIndicatorView(Context context, final float widthPixel, final float heightPixel,\n                                         final int color) {\n        ImageView indicator = new ImageView(context);\n        Drawable drawable = new Drawable() {\n            @Override\n            public void draw(Canvas canvas) {\n                Path path = new Path();\n                Paint paint = new Paint();\n                paint.setColor(color);\n                paint.setStyle(Paint.Style.FILL);\n                path.moveTo(0f, 0f);\n                path.lineTo(widthPixel, 0f);\n                path.lineTo(widthPixel / 2, heightPixel);\n                path.close();\n                canvas.drawPath(path, paint);\n            }\n\n            @Override\n            public void setAlpha(int alpha) {\n\n            }\n\n            @Override\n            public void setColorFilter(ColorFilter colorFilter) {\n\n            }\n\n            @Override\n            public int getOpacity() {\n                return PixelFormat.TRANSLUCENT;\n            }\n\n            @Override\n            public int getIntrinsicWidth() {\n                return (int) widthPixel;\n            }\n\n            @Override\n            public int getIntrinsicHeight() {\n                return (int) heightPixel;\n            }\n        };\n        indicator.setImageDrawable(drawable);\n        return indicator;\n    }\n\n    public void setIndicatorView(View indicatorView) {\n        this.mIndicatorView = indicatorView;\n    }\n\n    public void setIndicatorSize(int widthPixel, int heightPixel) {\n        this.mIndicatorWidth = widthPixel;\n        this.mIndicatorHeight = heightPixel;\n        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(mIndicatorWidth, mIndicatorHeight);\n        layoutParams.gravity = Gravity.CENTER;\n        if (mIndicatorView != null) {\n            mIndicatorView.setLayoutParams(layoutParams);\n        }\n    }\n\n    public int getNormalTextColor() {\n        return mNormalTextColor;\n    }\n\n    public void setNormalTextColor(int normalTextColor) {\n        this.mNormalTextColor = normalTextColor;\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    public int getPressedTextColor() {\n        return mPressedTextColor;\n    }\n\n    public void setPressedTextColor(int pressedTextColor) {\n        this.mPressedTextColor = pressedTextColor;\n        refreshTextColorStateList(mPressedTextColor, mNormalTextColor);\n    }\n\n    public float getTextSize() {\n        return mTextSize;\n    }\n\n    public void setTextSize(float textSizePixel) {\n        this.mTextSize = textSizePixel;\n    }\n\n    public int getTextPaddingLeft() {\n        return mTextPaddingLeft;\n    }\n\n    public void setTextPaddingLeft(int textPaddingLeft) {\n        this.mTextPaddingLeft = textPaddingLeft;\n    }\n\n    public int getTextPaddingTop() {\n        return mTextPaddingTop;\n    }\n\n    public void setTextPaddingTop(int textPaddingTop) {\n        this.mTextPaddingTop = textPaddingTop;\n    }\n\n    public int getTextPaddingRight() {\n        return mTextPaddingRight;\n    }\n\n    public void setTextPaddingRight(int textPaddingRight) {\n        this.mTextPaddingRight = textPaddingRight;\n    }\n\n    public int getTextPaddingBottom() {\n        return mTextPaddingBottom;\n    }\n\n    public void setTextPaddingBottom(int textPaddingBottom) {\n        this.mTextPaddingBottom = textPaddingBottom;\n    }\n\n    /**\n     * @param left   the left padding in pixels\n     * @param top    the top padding in pixels\n     * @param right  the right padding in pixels\n     * @param bottom the bottom padding in pixels\n     */\n    public void setTextPadding(int left, int top, int right, int bottom) {\n        this.mTextPaddingLeft = left;\n        this.mTextPaddingTop = top;\n        this.mTextPaddingRight = right;\n        this.mTextPaddingBottom = bottom;\n    }\n\n    public int getNormalBackgroundColor() {\n        return mNormalBackgroundColor;\n    }\n\n    public void setNormalBackgroundColor(int normalBackgroundColor) {\n        this.mNormalBackgroundColor = normalBackgroundColor;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getPressedBackgroundColor() {\n        return mPressedBackgroundColor;\n    }\n\n    public void setPressedBackgroundColor(int pressedBackgroundColor) {\n        this.mPressedBackgroundColor = pressedBackgroundColor;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getBackgroundCornerRadius() {\n        return mBackgroundCornerRadius;\n    }\n\n    public void setBackgroundCornerRadius(int backgroundCornerRadiusPixel) {\n        this.mBackgroundCornerRadius = backgroundCornerRadiusPixel;\n        refreshBackgroundOrRadiusStateList();\n    }\n\n    public int getDividerColor() {\n        return mDividerColor;\n    }\n\n    public void setDividerColor(int dividerColor) {\n        this.mDividerColor = dividerColor;\n    }\n\n    public int getDividerWidth() {\n        return mDividerWidth;\n    }\n\n    public void setDividerWidth(int dividerWidthPixel) {\n        this.mDividerWidth = dividerWidthPixel;\n    }\n\n    public int getDividerHeight() {\n        return mDividerHeight;\n    }\n\n    public void setDividerHeight(int dividerHeightPixel) {\n        this.mDividerHeight = dividerHeightPixel;\n    }\n\n    public Resources getResources() {\n        if (mContext == null) {\n            return Resources.getSystem();\n        } else {\n            return mContext.getResources();\n        }\n    }\n\n    private int getViewWidth(View view) {\n        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));\n        return view.getMeasuredWidth();\n    }\n\n    private int getViewHeight(View view) {\n        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));\n        return view.getMeasuredHeight();\n    }\n\n    public int dp2px(float value) {\n        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,\n                value, getResources().getDisplayMetrics());\n    }\n\n    public int sp2px(float value) {\n        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,\n                value, getResources().getDisplayMetrics());\n    }\n\n    public interface PopupListListener {\n\n        /**\n         * Whether the PopupList should be bound to the special view\n         *\n         * @param adapterView     The context view(The AbsListView where the click happened or normal view).\n         * @param contextView     The view within the AbsListView that was clicked or normal view\n         * @param contextPosition The position of the view in the list\n         * @return true if the view should bind the PopupList, false otherwise\n         */\n        boolean showPopupList(View adapterView, View contextView, int contextPosition);\n\n        /**\n         * The callback to be invoked with an item in this PopupList has\n         * been clicked\n         *\n         * @param contextView     The context view(The AbsListView where the click happened or normal view).\n         * @param contextPosition The position of the view in the list\n         * @param position        The position of the view in the PopupList\n         */\n        void onPopupListClick(View contextView, int contextPosition, int position);\n    }\n\n    public interface AdapterPopupListListener extends PopupListListener {\n        String formatText(View adapterView, View contextView, int contextPosition, int position, String text);\n    }\n\n}\n\n"
  },
  {
    "path": "samples/src/main/java/com/frank/sample/MainActivity.java",
    "content": "package com.frank.sample;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.View;\nimport android.widget.AdapterView;\nimport android.widget.ArrayAdapter;\nimport android.widget.Button;\nimport android.widget.ListView;\nimport android.widget.Toast;\n\nimport com.frank.popuplist.PopupList;\nimport com.frank.popuplist.R;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private Button btn_long_click;\n    private ListView lv_main;\n    private List<String> mDataList = new ArrayList<>();\n    private ArrayAdapter<String> mDataAdapter;\n    private List<String> popupMenuItemList = new ArrayList<>();\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        btn_long_click = (Button) findViewById(R.id.btn_long_click);\n        lv_main = (ListView) findViewById(R.id.lv_main);\n        mDataAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, mDataList);\n        lv_main.setAdapter(mDataAdapter);\n\n        popupMenuItemList.add(getString(R.string.copy));\n        popupMenuItemList.add(getString(R.string.delete));\n        popupMenuItemList.add(getString(R.string.share));\n        popupMenuItemList.add(getString(R.string.more));\n        PopupList popupList = new PopupList(this);\n        popupList.bind(lv_main, popupMenuItemList, new PopupList.PopupListListener() {\n            @Override\n            public boolean showPopupList(View adapterView, View contextView, int contextPosition) {\n                return true;\n            }\n\n            @Override\n            public void onPopupListClick(View contextView, int contextPosition, int position) {\n                Toast.makeText(MainActivity.this, contextPosition + \",\" + position, Toast.LENGTH_SHORT).show();\n            }\n        });\n\n        PopupList normalViewPopupList = new PopupList(this);\n        normalViewPopupList.bind(btn_long_click, popupMenuItemList, new PopupList.PopupListListener() {\n            @Override\n            public boolean showPopupList(View adapterView, View contextView, int contextPosition) {\n                return true;\n            }\n\n            @Override\n            public void onPopupListClick(View contextView, int contextPosition, int position) {\n                Toast.makeText(MainActivity.this, contextPosition + \",\" + position, Toast.LENGTH_SHORT).show();\n            }\n        });\n\n        lv_main.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n            @Override\n            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n                Toast.makeText(MainActivity.this, \"onItemClicked:\" + position, Toast.LENGTH_SHORT).show();\n            }\n        });\n        btn_long_click.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                startActivity(new Intent(MainActivity.this, SecondaryActivity.class));\n            }\n        });\n        getData();\n    }\n\n    private void getData() {\n        for (int i = 0; i < 40; i++) {\n            mDataList.add(\"No.\" + i);\n        }\n        mDataAdapter.notifyDataSetChanged();\n    }\n\n}\n"
  },
  {
    "path": "samples/src/main/java/com/frank/sample/SecondaryActivity.java",
    "content": "package com.frank.sample;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.widget.AdapterView;\nimport android.widget.ArrayAdapter;\nimport android.widget.ListView;\nimport android.widget.Toast;\n\nimport com.frank.popuplist.PopupList;\nimport com.frank.popuplist.R;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class SecondaryActivity extends AppCompatActivity {\n\n    private ListView lv_main;\n    private List<String> mDataList = new ArrayList<>();\n    private ArrayAdapter<String> mDataAdapter;\n    private List<String> popupMenuItemList = new ArrayList<>();\n    private float mRawX;\n    private float mRawY;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_secondary);\n        lv_main = (ListView) findViewById(R.id.lv_main);\n        mDataAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, mDataList);\n        lv_main.setAdapter(mDataAdapter);\n\n        popupMenuItemList.add(getString(R.string.copy));\n        popupMenuItemList.add(getString(R.string.delete));\n        popupMenuItemList.add(getString(R.string.share));\n        popupMenuItemList.add(getString(R.string.more));\n\n        lv_main.setOnTouchListener(new View.OnTouchListener() {\n            @Override\n            public boolean onTouch(View v, MotionEvent event) {\n                mRawX = event.getRawX();\n                mRawY = event.getRawY();\n                return false;\n            }\n        });\n        lv_main.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n            @Override\n            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n                Toast.makeText(SecondaryActivity.this, \"onItemClicked:\" + position, Toast.LENGTH_SHORT).show();\n            }\n        });\n        lv_main.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {\n            @Override\n            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {\n                int[] location = new int[2];\n                view.getLocationOnScreen(location);\n                PopupList popupList = new PopupList(view.getContext());\n                popupList.showPopupListWindow(view, position, location[0] + view.getWidth() / 2,\n                        location[1], popupMenuItemList, new PopupList.PopupListListener() {\n                            @Override\n                            public boolean showPopupList(View adapterView, View contextView, int contextPosition) {\n                                return true;\n                            }\n\n                            @Override\n                            public void onPopupListClick(View contextView, int contextPosition, int position) {\n                                Toast.makeText(contextView.getContext(), contextPosition + \",\" + position, Toast.LENGTH_SHORT).show();\n                            }\n                        });\n                return true;\n            }\n        });\n        getData();\n    }\n\n    private void getData() {\n        for (int i = 0; i < 40; i++) {\n            mDataList.add(\"No.\" + i);\n        }\n        mDataAdapter.notifyDataSetChanged();\n    }\n\n}\n"
  },
  {
    "path": "samples/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <Button\n        android:id=\"@+id/btn_long_click\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/app_name\" />\n\n    <ListView\n        android:id=\"@+id/lv_main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginLeft=\"100px\"\n        android:layout_marginRight=\"100px\"\n        android:layout_below=\"@id/btn_long_click\" />\n</RelativeLayout>\n"
  },
  {
    "path": "samples/src/main/res/layout/activity_secondary.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <ListView\n        android:id=\"@+id/lv_main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</RelativeLayout>\n"
  },
  {
    "path": "samples/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "samples/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "samples/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">PopupList</string>\n    <string name=\"copy\">复制</string>\n    <string name=\"delete\">删除</string>\n    <string name=\"share\">分享</string>\n    <string name=\"more\">更多&#8230;</string>\n</resources>\n"
  },
  {
    "path": "samples/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "samples/src/main/res/values-en/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">PopupList</string>\n    <string name=\"copy\">Copy</string>\n    <string name=\"delete\">Delete</string>\n    <string name=\"share\">Share</string>\n    <string name=\"more\">More&#8230;</string>\n</resources>\n"
  },
  {
    "path": "samples/src/main/res/values-w820dp/dimens.xml",
    "content": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "samples/src/test/java/com/frank/popuplist/ExampleUnitTest.java",
    "content": "package com.frank.popuplist;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch the Test Artifact in the Build Variants view.\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "settings.gradle",
    "content": "include ':samples'\n"
  }
]