Commit 0ec80f36 by maiqh

init

parents
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/notouchsupport-master-363f32dfdde8c261ff34621299138f697bab2bec" />
<option value="$PROJECT_DIR$/rvHelpers" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="D:\SDK\extras\m2repository" />
<option name="name" value="D:\SDK\extras\m2repository" />
<option name="url" value="file:/D:/SDK/extras/m2repository" />
</remote-repository>
<remote-repository>
<option name="id" value="D:\SDK\extras\google\m2repository" />
<option name="name" value="D:\SDK\extras\google\m2repository" />
<option name="url" value="file:/D:/SDK/extras/google/m2repository" />
</remote-repository>
<remote-repository>
<option name="id" value="D:\SDK\extras\android\m2repository" />
<option name="name" value="D:\SDK\extras\android\m2repository" />
<option name="url" value="file:/D:/SDK/extras/android/m2repository" />
</remote-repository>
<remote-repository>
<option name="id" value="D:\SDK\extras\android\m2repository" />
<option name="name" value="D:\SDK\extras\android\m2repository" />
<option name="url" value="file:/D:/SDK/extras/android/m2repository/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
defaultConfig {
applicationId "com.example.recyclerviewdemo2"
minSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation project(path: ':rvHelpers')
implementation project(path: ':notouchsupport-master-363f32dfdde8c261ff34621299138f697bab2bec')
// implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
compile 'com.android.support:recyclerview-v7:22.+'
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.example.recyclerviewdemo2;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.recyclerviewdemo2", appContext.getPackageName());
}
}
\ No newline at end of file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.recyclerviewdemo2">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<meta-data
android:name="cneeds_launcher_item_view"
android:value="com.example.recyclerviewdemo2.view.ItemView" />
<meta-data
android:name="cneeds_launcher_divider_view"
android:value="com.example.recyclerviewdemo2.view.ItemView" />
<meta-data
android:name="cneeds_launcher_item_view_order_id"
android:resource="@integer/launcher_index" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".GridRecyclerActivity"/>
</application>
</manifest>
\ No newline at end of file
package com.example.recyclerviewdemo2;
import android.view.ViewGroup;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
import com.cneeds.rvhelpers.viewholder.BaseViewHolder;
import com.cneeds.rvhelpers.viewholder.ContentHolder;
import com.cneeds.rvhelpers.viewholder.TitleHolder;
import java.util.List;
public class CustomerAdapter extends GridRecyclerAdapter {
/**
* @param dataList
* @param spanCount The number of columns in the grid
*/
public CustomerAdapter(List dataList, int spanCount) {
super(dataList, spanCount);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM_HEADER) {
// 这里返回你的标题ViewHolder
return new TitleHolder(parent.getContext(), parent);
} else {
// 这里返回你的内容ViewHolder
return new ContentHolder(parent.getContext(), parent);
}
}
}
package com.example.recyclerviewdemo2;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvHello = (TextView) findViewById(R.id.tv_hello);
tvHello.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GridRecyclerActivity.startUp(MainActivity.this);
}
});
}
}
package com.example.recyclerviewdemo2.view;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* author: jack
* date: 2018/8/30 18:12
* desc:Launcher界面基类
*/
public abstract class BaseLauncherView extends RelativeLayout {
private static final String TAG = "BaseLauncherView";
//UI state
public static final int STATE_NO_CONNECT = 0;
public static final int STATE_CONNECT = 1;
public static final int STATE_CALL = 2;
protected final Context mContext;
protected Context mReadResContext;
//view
protected RelativeLayout mRlRoot;
public BaseLauncherView(Context context) {
this(context, null);
}
public BaseLauncherView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BaseLauncherView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
try {
mReadResContext = mContext.createPackageContext(Constants.PACKAGE_NAME, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
onInit(context, attrs, defStyleAttr);
}
public abstract void onInit(Context context, AttributeSet attrs, int defStyleAttr);
/**
* 启动App
*/
protected void startupApp() {
Intent targetIntent = getContext().getPackageManager().getLaunchIntentForPackage(Constants.PACKAGE_NAME);
mContext.startActivity(targetIntent);
}
protected void toHome() {
Intent home = new Intent(Intent.ACTION_MAIN);
home.addCategory(Intent.CATEGORY_HOME);
getContext().startActivity(home);
}
}
package com.example.recyclerviewdemo2.view;
public class Constants {
//应用包名
public static final String PACKAGE_NAME = "com.example.recyclerviewdemo2";
}
package com.example.recyclerviewdemo2.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import com.example.recyclerviewdemo2.R;
public class ItemView extends BaseLauncherView{
public ItemView(Context context) {
super(context);
}
@Override
public void onInit(Context context, AttributeSet attrs, int defStyleAttr) {
LayoutInflater.from(context).inflate(R.layout.launcher_view, this);
LinearLayout root = (LinearLayout) findViewById(R.id.ll_root);
root.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startupApp();
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- 实线边框+内部填充 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:useLevel="true">
<stroke
android:width="3px"
android:color="#66E5FF" />
<solid android:color="#00000000" />
<!-- android:radius 圆角的半径 -->
<corners
android:radius="4px"
/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@color/gray_555659"/>
<item android:state_focused="true" android:color="@color/gray_555659"/>
<item android:state_pressed="true" android:color="@color/gray_555659"/>
<item android:color="@color/white"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/bg_0c0d11"
android:paddingRight="10dp"
android:paddingLeft="10dp"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:paddingTop="20dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28sp"
android:layout_gravity="center"
android:gravity="center"
android:textColor="@color/white"
android:text="抓拍照片"/>
<LinearLayout
android:id="@+id/ll_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|center_vertical"
android:layout_gravity="right|center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:drawableLeft="@drawable/img_record_edit"
android:drawablePadding="10dp"
android:textColor="@drawable/text_color"
android:padding="2dp"
android:text="编辑"/>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:layout_marginRight="50dp"
android:visibility="gone"
android:textColor="@drawable/text_color"
android:text="取消"/>
<TextView
android:id="@+id/tv_select_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:layout_marginRight="50dp"
android:visibility="gone"
android:textColor="@drawable/text_color"
android:text="全选"/>
<ImageView
android:id="@+id/iv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="22sp"
android:src="@drawable/img_record_delete_enabled"
/>
</LinearLayout>
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:layout_height="1dp"
android:background="@color/white_1affffff"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="70sp"
android:layout_gravity="center"
android:text="点击我进入Demo"/>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ll_root"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="RecyclerViewDemo"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#ffffff</color>
<color name="white_1affffff">#1affffff</color>
<color name="black">#000000</color>
<color name="blue">#1784ff</color>
<color name="theme_color">@color/black</color>
<color name="container_color">@color/white</color>
<color name="bg_0c0d11">#0c0d11</color>
<color name="gray_555659">#555659</color>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="launcher_index">7</integer>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">RecyclerViewDemo2</string>
</resources>
\ No newline at end of file
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
<item name="android:windowAnimationStyle">@style/Animation</item>
</style>
<style name="MyAppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
<item name="android:colorEdgeEffect">#666666</item>
</style>
<style name="Animation">
<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>
<item name="android:taskOpenEnterAnimation">@null</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@null</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@null</item>
</style>
</resources>
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:3.1.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
\ No newline at end of file
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
\ No newline at end of file
#Thu Jul 16 20:18:05 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_3">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/notouchsupport.iml" filepath="$PROJECT_DIR$/notouchsupport.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="e78725d5-a6ca-4df3-86ea-93a28f12f089" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExternalProjectsManager">
<system id="GRADLE">
<state>
<projects_view />
</state>
</system>
</component>
<component name="ProjectId" id="1eqy95qVYz1056EjhVC0e8cXwOm" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showExcludedFiles" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="android.project.structure.last.selected" value="SDK Location" />
<property name="android.project.structure.proportion" value="0.15" />
<property name="android.sdk.path" value="$USER_HOME$/AppData/Local/Android/cneeds_sdk" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="preferences.keymap" />
</component>
<component name="RunManager">
<configuration name="&lt;template&gt;" type="Applet" default="true" selected="false">
<option name="MAIN_CLASS_NAME" />
<option name="HTML_FILE_NAME" />
<option name="HTML_USED" value="false" />
<option name="WIDTH" value="400" />
<option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<option name="VM_PARAMETERS" />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
<configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="TestNG">
<option name="TEST_OBJECT" value="CLASS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<properties />
<listeners />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="e78725d5-a6ca-4df3-86ea-93a28f12f089" name="Default Changelist" comment="" />
<created>1584586132960</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1584586132960</updated>
</task>
<servers />
</component>
<component name="masterDetails">
<states>
<state key="ScopeChooserConfigurable.UI">
<settings>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
defaultConfig {
minSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
}
#Thu Mar 19 09:53:17 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sat Jul 18 17:07:45 CST 2020
ndk.dir=C\:\\Users\\LeoHo\\AppData\\Local\\Android\\cneeds_sdk\\ndk-bundle
sdk.dir=D\:\\SDK
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.cneeds.notouch;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.cneeds.notouch.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cneeds.notouch" />
package com.cneeds.notouch;
public class NoTouchConstant {
public static final String FOCUS_STATUS_URL = "content://com.android.systemui.statusbar.phone/Focus/1";
public static final String FOCUS_NEED_URL = "content://com.android.systemui.statusbar.phone/Focus/2";
public static final int FOCUS_COLUMN_INDEX = 0;
public static final int MAX_VALUE = -2;
public static final int INIT_KEY_CODE = -10001;
public static class OperationConstant{
public static final int MIN_VALID_VALUE = 0;
public static final int INTERVAL_VALUE = 1;
public static final int NONE_VALUE = -1;
}
public static class SpecialFlag{
public static final int NO_NEED_FOCUS_FLAG = 1;
public static final int SINGLE_LEVEL_FLAG = 2;
//多层级选中及进入
public static final int DOUBLE_LEVEL_HORIZONTAL_FLAG = 3;
public static final int DOUBLE_LEVEL_VERTICAL_FLAG = 4;
public static final int SINGLE_BAIDU_LEVEL_FLAG = 5;
public static final int DIALOG_LEVEL_FLAG = 6;
public static final int BAIDU_DIALOG_LEVEL_FLAG = 7;
//新增单层类型,在第一个位置左旋focus不会主动回到SystemUI
public static final int SINGLE_LEVEL_FLAG2 = 8;
}
public static class FocusStatus{
public static final int NONE = 0;
public static final int NEW = 0;
public static final int RECOVER = 1;
}
public static class Focus{
public static final int SYSTEM_BAR_FOCUS = 1;
public static final int APP_FOCUS = 2;
}
public static class OperationFlag{
public static final int OPERATION_NONE = 1;
public static final int OPERATION_NO_FOCUS = 2;
public static final int OPERATION_SELECTED = 3;
public static final int OPERATION_ENTER = 4;
}
public static class ColumnName{
public static final String COLUMN_FOCUS_STATE = "focus_state";
public static final String COLUMN_FOCUS_NAME = "focus_name";
public static final String COLUMN_FOCUS_NEED = "focus_need";
public static final String COLUMN_FOCUS_KEY = "focus_key";
public static final String COLUMN_FOCUS_TEMP = "focus_temp";
}
public static class OperationResult{
public static final int SUCCESS = 0;
public static final int SAME = 2;
public static final int FAIL = 1;
public static final int LOADING = 3;
}
public static class CoordinateLevel{
public static final int LEVEL_0 = 0;
public static final int LEVEL_1 = 1;
}
public static class OperationFailCount{
public static final int FAIL_NONE = 0;
public static final int FAIL_ONE = 1;
public static final int FAIL_TWO = 2;
public static final int FAIL_THIRD = 3;
public static final int FAIL_FOUR = 4;
}
}
package com.cneeds.notouch;
import com.cneeds.notouch.bean.ActivityOperationBean;
import com.cneeds.notouch.bean.CoordinateBean;
public interface NoTouchListener {
ActivityOperationBean onSelectedChange(CoordinateBean coordinateBean);
ActivityOperationBean onSelectedEnter(CoordinateBean coordinateBean);
ActivityOperationBean onSelectNone();
}
package com.cneeds.notouch;
import android.util.Log;
public class NoTouchLog {
private static final String TAG = "NoTouchLog";
public static void d(String str){
Log.d(TAG, str);
}
}
package com.cneeds.notouch;
import android.content.Context;
import android.view.KeyEvent;
import com.cneeds.notouch.bean.CoordinateBean;
/**
* 非触控管理类,提供外部调用的接口
* @author zhany
*/
public class NoTouchManager {
protected NoTouchManager(){
}
private static final class NoTouchManagerHolder{
private static final NoTouchManager INSTANCE = new NoTouchManager();
}
public static NoTouchManager getInstance(){
return NoTouchManagerHolder.INSTANCE;
}
private NoTouchFocusController mNoTouchFocusController;
/**
* 初始化
* @param context 建议传递Application的context
*/
public void init(Context context){
mNoTouchFocusController = new NoTouchFocusController(context);
}
/**
* 注册非触控监听
* @param listener
* @param noTouchParam
*/
public void registerNoTouchListener(NoTouchListener listener, NoTouchParam noTouchParam){
mNoTouchFocusController.registerNoTouchListener(listener, noTouchParam);
}
/**
* 在View销毁,Activity不在前台的情况下需要移除非触控监听。
* @param listener
*/
public void unRegisterNoTouchListener(NoTouchListener listener){
mNoTouchFocusController.unRegisterNoTouchListener(listener);
}
/**
* 设置临时的注册,主要为了一些特殊页面,比如当前为A 通过这个注册后会变成B,
* 取消注册的时候会恢复A
* @param packageName
*/
public void registerNoTouchTempListener(String packageName){
mNoTouchFocusController.registerNoTouchTempListener(packageName);
}
public void unRegisterNoTouchTempListener(String packageName){
mNoTouchFocusController.unRegisterNoTouchTempListener(packageName);
}
/**
* View或者Activity收到系统onkeyDown的调用后调用此方法。
* @param keyCode
* @param keyEvent
*/
public void onKeyDown(int keyCode, KeyEvent keyEvent){
mNoTouchFocusController.onKeyDown(keyCode, keyEvent);
}
/**
* 设置恢复的位置
* @param className
* @param coordinateBean
*/
public void setRecoverCoordinateBean(String className, CoordinateBean coordinateBean){
mNoTouchFocusController.setRecoverCoordinateBean(className , coordinateBean);
}
/**
* 获取是否支持hardkey
* @return
*/
public boolean getSupportHardKey(){
return mNoTouchFocusController.getSupportHardKey();
}
public boolean checkUseKeyCode(int keyCode){
return mNoTouchFocusController.checkUseKeyCode(keyCode);
}
/****
* 以下为页面自己处理点击事件的接口
* **************************************************
*/
public void registerSelfListener(NoTouchSelfListener selfListener){
mNoTouchFocusController.registerSelfListener(selfListener);
}
public void unRegisterSelfListener(NoTouchSelfListener selfListener){
mNoTouchFocusController.unRegisterSelfListener(selfListener);
}
public void cancelFocus(){
mNoTouchFocusController.cancelFocus();
}
/**
* *******************************************************************8
*/
}
package com.cneeds.notouch;
import com.cneeds.notouch.bean.CoordinateBean;
import java.util.ArrayList;
import java.util.List;
public class NoTouchParam {
private final int SPECIAL_FLAG;
private final int FOCUS_STATUS;
private final String CLASS_NAME;
private final boolean CALL_BACK_NOW;
private CoordinateBean COORDINATE_BEAN;
private final boolean NO_NAVIGATION_BAR;
protected NoTouchParam(Builder builder){
SPECIAL_FLAG = builder.mSpecialFlag;
FOCUS_STATUS = builder.mFocusStatus;
CLASS_NAME = builder.mClassName;
CALL_BACK_NOW = builder.mCallBackNow;
NO_NAVIGATION_BAR = builder.mNoNavigationBar;
if(builder.mCoordinateBean != null){
COORDINATE_BEAN = builder.mCoordinateBean.copyCoordinate();
}else{
COORDINATE_BEAN = null;
}
}
public int getFocusStatus(){
return FOCUS_STATUS;
}
public String getClassName(){
return CLASS_NAME;
}
public int getSpecialFlag(){
return SPECIAL_FLAG;
}
public boolean getCurrentCallBack() {
return CALL_BACK_NOW;
}
public boolean getNoNavigationBar() {
return NO_NAVIGATION_BAR;
}
public CoordinateBean getInitCoordinateBean(){
return COORDINATE_BEAN;
}
public static class Builder{
private int mSpecialFlag;
private int mFocusStatus = NoTouchConstant.FocusStatus.NEW;
private boolean mCallBackNow;
private String mClassName;
private CoordinateBean mCoordinateBean;
private boolean mNoNavigationBar;
/**
* {@link com.cneeds.notouch.NoTouchConstant.SpecialFlag}
* @param specialFlag
* @return
*/
public Builder setSpecialFlag(int specialFlag){
mSpecialFlag = specialFlag;
return this;
}
/**
* {@link com.cneeds.notouch.NoTouchConstant.FocusStatus}
* @param focusStatus
* @return
*/
public Builder setFocusStatus(int focusStatus){
mFocusStatus = focusStatus;
return this;
}
public Builder setCallBackNow(boolean nowCallBackNow){
mCallBackNow = nowCallBackNow;
return this;
}
public Builder setClassName(String className){
mClassName = className;
return this;
}
public Builder setInitCoordinateBean(CoordinateBean coordinateBean){
mCoordinateBean = coordinateBean;
return this;
}
public Builder setNoNavigationBar(boolean noNavigationBar){
mNoNavigationBar = noNavigationBar;
return this;
}
public NoTouchParam build(){
return new NoTouchParam(this);
}
}
}
package com.cneeds.notouch;
public interface NoTouchSelfListener {
void onFocusChange(int focusState);
}
package com.cneeds.notouch.bean;
public class ActivityOperationBean {
private int operationResult;
/**
* 传递最大值变量的时候这个字段必须赋值
*/
private CoordinateBean coordinateBean;
public int getOperationResult() {
return operationResult;
}
public void setOperationResult(int operationResult) {
this.operationResult = operationResult;
}
public CoordinateBean getCoordinateBean() {
return coordinateBean;
}
public void setCoordinateBean(CoordinateBean coordinateBean) {
this.coordinateBean = coordinateBean;
}
}
package com.cneeds.notouch.bean;
public class CoordinateBean {
private int x;
private int y;
private int xx;
private int yy;
public int getXx() {
return xx;
}
public void setXx(int xx) {
this.xx = xx;
}
public int getYy() {
return yy;
}
public void setYy(int yy) {
this.yy = yy;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public CoordinateBean copyCoordinate(){
CoordinateBean coordinateBean = new CoordinateBean();
coordinateBean.x = this.x;
coordinateBean.y = this.y;
coordinateBean.xx = this.xx;
coordinateBean.yy = this.yy;
return coordinateBean;
}
public void copyCoordinate(CoordinateBean coordinateBean){
x = coordinateBean.x;
y = coordinateBean.y;
xx = coordinateBean.xx;
yy = coordinateBean.yy;
}
}
package com.cneeds.notouch.bean;
public class OperationBean {
private int operationFlag;
private CoordinateBean coordinateBean;
public int getOperationFlag() {
return operationFlag;
}
/**
* {@link com.cneeds.notouch.NoTouchConstant.OperationFlag}
* @param operationFlag
*/
public void setOperationFlag(int operationFlag) {
this.operationFlag = operationFlag;
}
public CoordinateBean getCoordinateBean() {
return coordinateBean;
}
public void setCoordinateBean(CoordinateBean coordinateBean) {
this.coordinateBean = coordinateBean;
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchConstant;
import com.cneeds.notouch.NoTouchFocusController;
import com.cneeds.notouch.NoTouchLog;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.ActivityOperationBean;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.CoordinateLevel.LEVEL_0;
import static com.cneeds.notouch.NoTouchConstant.CoordinateLevel.LEVEL_1;
import static com.cneeds.notouch.NoTouchConstant.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
import static com.cneeds.notouch.NoTouchConstant.OperationResult.LOADING;
import static com.cneeds.notouch.NoTouchConstant.OperationResult.SAME;
import static com.cneeds.notouch.NoTouchConstant.OperationResult.SUCCESS;
public abstract class AbsNoTouchOperation implements NoTouchOperation{
protected NoTouchFocusController.ActivityOperationListener mOperationListener;
private CoordinateBean mCoordinateBean;
private int mFailCount = 0;
private NoTouchParam mNoTouchParam;
protected AbsNoTouchOperation(NoTouchParam param){
mNoTouchParam = param;
}
protected NoTouchParam getNoTouchParam(){
return mNoTouchParam;
}
@Override
public void registerActivityOperationResult(NoTouchFocusController.ActivityOperationListener operationListener) {
mOperationListener = operationListener;
}
@Override
public void operation(int keyCode, KeyEvent keyEvent) {
NoTouchLog.d("keyCode = " + keyCode);
if(mOperationListener == null){
try {
throw new Exception("registerActivityOperationResult no call");
} catch (Exception e) {
e.printStackTrace();
}
}
while(true){
OperationBean operationBean;
if(mCoordinateBean == null){
operationBean = getInitOperationBean();
if(mNoTouchParam.getInitCoordinateBean() != null){
operationBean.setCoordinateBean(mNoTouchParam.getInitCoordinateBean().copyCoordinate());
}
}else{
if(keyCode == NoTouchConstant.INIT_KEY_CODE){
return;
}
operationBean = operationReal(keyCode, keyEvent);
}
NoTouchLog.d("operationBean OperationFlag = " + operationBean.getOperationFlag());
if(operationBean.getOperationFlag() == OPERATION_NO_FOCUS
&& mNoTouchParam.getNoNavigationBar()){
mFailCount = 0;
break;
}
ActivityOperationBean activityOperationBean = mOperationListener.activityOperation(operationBean);
NoTouchLog.d("activityOperationBean result = " + activityOperationBean.getOperationResult());
if(activityOperationBean.getOperationResult() == LOADING){
mFailCount = 0;
break;
}
if(activityOperationBean.getOperationResult() == SAME){
if(activityOperationBean.getCoordinateBean() != null
&& existMaxValue(operationBean.getCoordinateBean())){
mCoordinateBean.copyCoordinate(activityOperationBean.getCoordinateBean());
continue;
}
if(mCoordinateBean == null){
mCoordinateBean = operationBean.getCoordinateBean().copyCoordinate();
}else{
mCoordinateBean.copyCoordinate(operationBean.getCoordinateBean());
}
continue;
}
if(activityOperationBean.getOperationResult() == SUCCESS){
if(operationBean.getOperationFlag() == OPERATION_NO_FOCUS){
mFailCount = 0;
break;
}
if(operationBean.getOperationFlag() != OPERATION_SELECTED){
mFailCount = 0;
break;
}
if(mCoordinateBean == null){
mCoordinateBean = operationBean.getCoordinateBean().copyCoordinate();
}else{
mCoordinateBean.copyCoordinate(operationBean.getCoordinateBean());
}
if(activityOperationBean.getCoordinateBean() != null
&& existMaxValue(operationBean.getCoordinateBean())){
mCoordinateBean.copyCoordinate(activityOperationBean.getCoordinateBean());
}
mFailCount = 0;
break;
}
mFailCount = mFailCount + 1;
}
}
protected final CoordinateBean getCoordinateBean(){
return mCoordinateBean;
}
protected final int getCoordinateLevel(CoordinateBean coordinateBean){
if(coordinateBean.getX() >= 1 && coordinateBean.getY() >= 1){
return LEVEL_0;
}
return LEVEL_1;
}
protected int getFailCount(){
return mFailCount;
}
protected boolean existMaxValue(CoordinateBean coordinateBean){
if(coordinateBean.getYy() == MAX_VALUE
|| coordinateBean.getXx() == MAX_VALUE
|| coordinateBean.getX() == MAX_VALUE
|| coordinateBean.getY() == MAX_VALUE){
return true;
}
return false;
}
@Override
public void restoreLastCoordinate() {
if(mCoordinateBean != null){
OperationBean operationBean = new OperationBean();
operationBean.setOperationFlag(OPERATION_SELECTED);
operationBean.setCoordinateBean(mCoordinateBean.copyCoordinate());
mOperationListener.activityOperation(operationBean);
}else{
operation(NoTouchConstant.INIT_KEY_CODE, null);
}
}
@Override
public void resetInitCoordinate() {
if(mCoordinateBean != null){
mCoordinateBean = getInitOperationBean().getCoordinateBean().copyCoordinate();
}
}
@Override
public void setLastCoordinate(CoordinateBean coordinate) {
if(mCoordinateBean != null){
mCoordinateBean.copyCoordinate(coordinate);
}
}
public abstract OperationBean operationReal(int keyCode, KeyEvent keyEvent);
public abstract OperationBean getInitOperationBean();
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_ONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_TWO;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_ENTER;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class DialogLevelOperation extends AbsNoTouchOperation{
private int LEVEL_0_MIN_VALUE = 0;
protected DialogLevelOperation(NoTouchParam param) {
super(param);
}
@Override
public OperationBean operationReal(int keyCode, KeyEvent keyEvent) {
OperationBean operationBean = new OperationBean();
operationBean.setCoordinateBean(getCoordinateBean().copyCoordinate());
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
leftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_UP:
upKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
rightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
downKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_LEFT:
shiftLeftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
shiftRightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_ENTER:
enterKeyEvent(operationBean);
break;
default:
break;
}
return operationBean;
}
@Override
public OperationBean getInitOperationBean() {
OperationBean operationBean = new OperationBean();
CoordinateBean coordinateBean = new CoordinateBean();
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_TWO:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(MAX_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void enterKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
operationBean.setOperationFlag(OPERATION_ENTER);
}
private void downKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void rightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void upKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchFocusController;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
public interface NoTouchOperation {
void operation(int keyCode , KeyEvent keyEvent);
void registerActivityOperationResult(NoTouchFocusController.ActivityOperationListener operationListener);
void restoreLastCoordinate();
void setLastCoordinate(CoordinateBean coordinate);
void resetInitCoordinate();
}
package com.cneeds.notouch.operation;
import com.cneeds.notouch.NoTouchParam;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.BAIDU_DIALOG_LEVEL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.DIALOG_LEVEL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.DOUBLE_LEVEL_HORIZONTAL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.DOUBLE_LEVEL_VERTICAL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.SINGLE_BAIDU_LEVEL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.SINGLE_LEVEL_FLAG;
import static com.cneeds.notouch.NoTouchConstant.SpecialFlag.SINGLE_LEVEL_FLAG2;
public class NoTouchOperationFactory {
public static NoTouchOperation createOperation(NoTouchParam noTouchParam){
switch (noTouchParam.getSpecialFlag()){
case SINGLE_LEVEL_FLAG:
return new SingleLevelOperation(noTouchParam);
case SINGLE_LEVEL_FLAG2:
return new SingleLevelOperation2(noTouchParam);
case DOUBLE_LEVEL_HORIZONTAL_FLAG:
return new DoubleLevelHorizontalOperation(noTouchParam);
case DOUBLE_LEVEL_VERTICAL_FLAG:
return new DoubleLevelVerticalOperation(noTouchParam);
case SINGLE_BAIDU_LEVEL_FLAG:
return new SingleBaiduOperation(noTouchParam);
case DIALOG_LEVEL_FLAG:
return new DialogLevelOperation(noTouchParam);
case BAIDU_DIALOG_LEVEL_FLAG:
return new SingleBaiduDialogOperation(noTouchParam);
default:
break;
}
return null;
}
}
package com.cneeds.notouch.operation;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.INTERVAL_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.NONE_VALUE;
public class OperationUtil {
public static int getNextOperation(int currentValue, int maxValue){
int tempValue = currentValue + INTERVAL_VALUE;
if(tempValue > maxValue ){
return NONE_VALUE;
}
return tempValue;
}
public static int getBeforeOperation(int currentValue){
int tempValue = currentValue - INTERVAL_VALUE;
if(tempValue <= NONE_VALUE ){
return NONE_VALUE;
}
return tempValue;
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_ONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_TWO;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_ENTER;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class SingleBaiduDialogOperation extends AbsNoTouchOperation{
private NoTouchParam mNoTouchParam;
private int LEVEL_0_MIN_VALUE = 0;
protected SingleBaiduDialogOperation(NoTouchParam param) {
super(param);
}
@Override
public OperationBean operationReal(int keyCode, KeyEvent keyEvent) {
OperationBean operationBean = new OperationBean();
operationBean.setCoordinateBean(getCoordinateBean().copyCoordinate());
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
leftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_UP:
upKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
rightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
downKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_LEFT:
shiftLeftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
shiftRightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_ENTER:
enterKeyEvent(operationBean);
break;
default:
break;
}
return operationBean;
}
@Override
public OperationBean getInitOperationBean() {
OperationBean operationBean = new OperationBean();
CoordinateBean coordinateBean = new CoordinateBean();
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_TWO:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void enterKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
operationBean.setOperationFlag(OPERATION_ENTER);
}
private void downKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void rightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void upKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
}
package com.cneeds.notouch.operation;
import android.util.Log;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchLog;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_ONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_TWO;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_ENTER;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class SingleBaiduOperation extends AbsNoTouchOperation{
private NoTouchParam mNoTouchParam;
private int LEVEL_0_MIN_VALUE = 0;
protected SingleBaiduOperation(NoTouchParam param) {
super(param);
}
@Override
public OperationBean operationReal(int keyCode, KeyEvent keyEvent) {
OperationBean operationBean = new OperationBean();
operationBean.setCoordinateBean(getCoordinateBean().copyCoordinate());
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
leftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_UP:
upKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
rightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
downKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_LEFT:
shiftLeftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
shiftRightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_ENTER:
enterKeyEvent(operationBean);
break;
default:
break;
}
return operationBean;
}
@Override
public OperationBean getInitOperationBean() {
OperationBean operationBean = new OperationBean();
CoordinateBean coordinateBean = new CoordinateBean();
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_TWO:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
private void enterKeyEvent(OperationBean operationBean) {
NoTouchLog.d("enterKeyEvent: OperationFlag=" + operationBean.getOperationFlag() + ", failcount=" + getFailCount());
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
operationBean.setOperationFlag(OPERATION_ENTER);
}
private void downKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void rightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void upKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_ONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_TWO;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_ENTER;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class SingleLevelOperation extends AbsNoTouchOperation{
private int LEVEL_0_MIN_VALUE = 0;
protected SingleLevelOperation(NoTouchParam param) {
super(param);
}
@Override
public OperationBean operationReal(int keyCode, KeyEvent keyEvent) {
OperationBean operationBean = new OperationBean();
operationBean.setCoordinateBean(getCoordinateBean().copyCoordinate());
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
leftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_UP:
upKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
rightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
downKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_LEFT:
shiftLeftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
shiftRightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_ENTER:
enterKeyEvent(operationBean);
break;
default:
break;
}
return operationBean;
}
@Override
public OperationBean getInitOperationBean() {
OperationBean operationBean = new OperationBean();
CoordinateBean coordinateBean = new CoordinateBean();
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_TWO:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(MAX_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
private void enterKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
operationBean.setOperationFlag(OPERATION_ENTER);
}
private void downKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void rightKeyEvent(OperationBean operationBean) {
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void upKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import static com.cneeds.notouch.NoTouchConstant.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_ONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFailCount.FAIL_TWO;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_ENTER;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_NONE;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
/**
* 描述:新增单层operation,这种类型在第一个时,再左旋不会主动把focus交还给SystemUI,
* 在最后一个再右旋,还会通过OPERATION_SELECTED返回,
* 由应用自己处理,用于展开多个fragment的情况
* Created by LeoHo on 2020/3/19.
*/
public class SingleLevelOperation2 extends AbsNoTouchOperation {
private int LEVEL_0_MIN_VALUE = 0;
protected SingleLevelOperation2(NoTouchParam param) {
super(param);
}
@Override
public OperationBean operationReal(int keyCode, KeyEvent keyEvent) {
OperationBean operationBean = new OperationBean();
operationBean.setCoordinateBean(getCoordinateBean().copyCoordinate());
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
leftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_UP:
upKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
rightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
downKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_LEFT:
shiftLeftKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
shiftRightKeyEvent(operationBean);
break;
case KeyEvent.KEYCODE_ENTER:
enterKeyEvent(operationBean);
break;
default:
break;
}
return operationBean;
}
@Override
public OperationBean getInitOperationBean() {
OperationBean operationBean = new OperationBean();
CoordinateBean coordinateBean = new CoordinateBean();
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
switch (getFailCount()) {
case FAIL_NONE: {
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE: {
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_TWO: {
operationBean.getCoordinateBean().setX(MAX_VALUE);
operationBean.getCoordinateBean().setY(MAX_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
default:
break;
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if (operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE) {
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
} else if (operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE) {
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
} else {
if (FAIL_NONE == getFailCount()) {
operationBean.getCoordinateBean().setX(MAX_VALUE);
} else {
operationBean.getCoordinateBean().setY(MAX_VALUE);
}
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
private void enterKeyEvent(OperationBean operationBean) {
if (getFailCount() == 1) {
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
operationBean.setOperationFlag(OPERATION_ENTER);
}
private void downKeyEvent(OperationBean operationBean) {
switch (getFailCount()) {
case FAIL_NONE: {
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE: {
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void rightKeyEvent(OperationBean operationBean) {
switch (getFailCount()) {
case FAIL_NONE: {
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE: {
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
private void upKeyEvent(OperationBean operationBean) {
if (operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE) {
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
} else {
operationBean.setOperationFlag(OPERATION_NONE);
}
}
private void leftKeyEvent(OperationBean operationBean) {
if (operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE) {
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
} else {
operationBean.getCoordinateBean().setX(MAX_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
}
package com.cneeds.notouch;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
/build
\ No newline at end of file
# 快捷使用
## 第一步:初始化显示数据,区分标题Item和普通Item
```
List<Object> dataList = new ArrayList<>();  
dataList.add(new HeaderBean("标题"));   
dataList.add(new ContentBean("图片路径")); 
```
## 第二步:给recyclerview添加LayoutManager和adapter,如下:
```
mLayoutManager = new CenterGridLayoutManager(context, SPAN_COUNT, dataList);
recyclerView.setLayoutManager(mLayoutManager);
mAdapter = new GridRecyclerAdapter<>(dataList, SPAN_COUNT);
recyclerView.setAdapter(mAdapter);
```
如果要粘性头效果还得添加:
```
recyclerView.addItemDecoration(new PinnedHeaderItemDecoration());
```
## 第三步:删除按钮处理 和 全选状态回调
在你的删除按钮的点击监听里调用:
```
mAdapter.deleteSelected()
```
全选状态监听:
```
mAdapter.setOnSelectListener(new GridRecyclerAdapter.OnSelectListener() {
@Override
public void onSelect(View v, int position, int selectedItemCount, int contentItemCount) {
if (mTvSelectAll != null && mTvSelectAll.getVisibility() == View.VISIBLE) {
if (selectedItemCount != contentItemCount) {
if ("全不选".equals(mTvSelectAll.getText())) {
mTvSelectAll.setText("全选");
}
} else {
if ("全选".equals(mTvSelectAll.getText())) {
mTvSelectAll.setText("全不选");
}
}
}
}
});
}
```
## 第四步:旋钮事件处理,
这个最麻烦,可以参考现有demo
### 4.1
```
public ActivityOperationBean onSelectedChange(CoordinateBean coordinateBean) {
ActivityOperationBean activityOperationBean = new ActivityOperationBean();
int x = coordinateBean.getX();
if (mAdapter != null) {
// 1. 获取到移动到下一个位置的adapter position
KeyEventHelper.PositionBean positionBean = mAdapter.moveToNext(coordinateBean.getX(), coordinateBean.getY());
coordinateBean.setY(positionBean.getY() + 1);
coordinateBean.setX(positionBean.getX());
int adapterPosition = positionBean.getAdapterPosition();
if (adapterPosition >= 0) {
// 2. 设置recyclerView滚动居中
mRvGrid.smoothScrollToPosition(adapterPosition);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
} else {
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.FAIL);
}
}
return activityOperationBean;
}
```
### 4.2
当焦点移出recyclerView区域时,需要调用,调用时机需要结合嵌入的界面:
```
mAdapter.setCurrentHighLight(GridRecyclerAdapter.NONE_SELECT);
```
可以用下面方法获取当前高亮的Item的Adapter的position,如果当前没有高亮位置返回GridRecyclerAdapter.NONE_SELECT
```
mAdapter.getCurrentHighLightPosition()
```
例子:一般会在onSelectNone调用
```
@Override
public ActivityOperationBean onSelectNone() {
if (mAdapter != null && mAdapter.getCurrentHighLightPosition() != GridRecyclerAdapter.NONE_SELECT) {
mAdapter.setCurrentHighLight(GridRecyclerAdapter.NONE_SELECT);
}
}
```
# 如果需要自定义,步骤如下:
## 第一步:标题类继承IHeader,区分标题Item和普通Item
```
public class 你的标题数据类 implements IHeader {  
          // do something ....  
```
## 第二步:继承BaseViewHolder,绑定你自定义的view和数据
```
1.public class 你的标题Holder类名 extends BaseViewHolder<你的标题数据类> {  
2.  
3.    public 你的标题Holder类名(Context context, ViewGroup root) {  
4.        super(context, root, 你的标题Item布局文件ID);  
5.        // do something ... e.g. findViewById  
6.    }  
7.  
8.    @Override  
9.    public void bindData(你的标题数据类 s, int position,   
10.                                 GridRecyclerAdapter adapter) {  
11.        // 绑定数据到View  
12.    }  
```
```
1.public class 你的内容Holder类名 extends BaseViewHolder<你的内容数据类> {  
2.  
3.    public 你的内容Holder类名(Context context, ViewGroup root) {  
4.        super(context, root, 你的内容Item布局文件ID);  
5.        // do something ... e.g. findViewById  
6.    }  
7.  
8.    @Override  
9.    public void bindData(你的内容数据类 s, int position,   
10.                                 GridRecyclerAdapter adapter) {  
11.        // 绑定数据到View  
12.    }  
```
## 第三步:继承GridRecyclerAdapter,重写onCreateViewHolder
```
public class CustomerAdapter extends GridRecyclerAdapter {
/**
* @param dataList
* @param spanCount The number of columns in the grid
*/
public CustomerAdapter(List dataList, int spanCount) {
super(dataList, spanCount);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM_HEADER) {
// 这里返回你的标题ViewHolder
} else{
// 这里返回你的内容ViewHolder
}
}
}
```
# 一些Adapter提供的数据
当前是否处于编辑模式:
```
adapter.getEditMode(); // true: 处于,false,不处于
```
在编辑模式中,判断当前item是否被选择(一般用于自定义ViewHolder)
```
boolean selected = adapter.isSelected(position);
```
在编辑模式中,通知adapter当前item选择状态被更改(一般用于自定义ViewHolder)
```
adapter.toggleSelection(v, finalPosition);
```
在旋钮事件响应时,判断当前item是否需要展示选中状态(一般用于自定义ViewHolder)
```
if (adapter.getCurrentHighLightPosition() == position)
```
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
defaultConfig {
minSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:recyclerview-v7:22.+'
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cneeds.rvhelpers">
</manifest>
\ No newline at end of file
package com.cneeds.rvhelpers;
import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
import com.cneeds.rvhelpers.entity.IHeader;
import java.util.List;
/**
* 参考博客:https://blog.csdn.net/iblade/article/details/90449089
* author: maiqh
*/
public class CenterGridLayoutManager extends GridLayoutManager {
public CenterGridLayoutManager(Context context, int spanCount, GridRecyclerAdapter adapter) {
super(context, spanCount);
init(adapter);
}
public CenterGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, GridRecyclerAdapter adapter) {
super(context, attrs, defStyleAttr, defStyleRes);
init(adapter);
}
private void init(final GridRecyclerAdapter adapter) {
setSpanSizeLookup(new SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (adapter.getDataList().get(position) instanceof IHeader) {
return getSpanCount();
} else {
return 1;
}
}
});
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private static class CenterSmoothScroller extends LinearSmoothScroller {
CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
// 滑动到中间
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
// @Override
// protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
// // 减低滑动速度,默认是25f
// return 50f / displayMetrics.densityDpi;
// }
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return null;
}
}
}
package com.cneeds.rvhelpers.adapter;
import android.support.v7.widget.RecyclerView;
public abstract class PinnedHeaderAdapter<VH extends RecyclerView.ViewHolder> extends SelectableAdapter<VH> {
/**
* 判断该position对应的位置是要固定
*
* @param position adapter position
* @return true or false
*/
public abstract boolean isPinnedPosition(int position);
}
package com.cneeds.rvhelpers.adapter;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mqh on 11/4/16.
*/
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private ArrayList<Object> mSelectedItems;
public SelectableAdapter() {
mSelectedItems = new ArrayList<>();
}
public boolean isSelected(Object dataBean) {
return getSelectedItems().contains(dataBean);
}
/**
* Toggle the selection status of the item at a given position
*
* @param position Position of the item to toggle the selection status for
*/
public boolean toggleSelection(int position, Object obj) {
boolean isChecked;
if (getSelectedItems().contains(obj)) {
getSelectedItems().remove(obj);
isChecked = false;
} else {
getSelectedItems().add(obj);
isChecked = true;
}
notifyItemChanged(position);
return isChecked;
}
/**
* Count the selected items
*
* @return Selected items count
*/
public int getSelectedItemCount() {
return getSelectedItems().size();
}
/**
* Indicates the list of selected items
*
* @return List of selected items ids
*/
public List getSelectedItems() {
if (mSelectedItems == null) {
mSelectedItems = new ArrayList<>();
}
return mSelectedItems;
}
/**
* Clear the selection status for all items
*/
public void clearAllSelection() {
getSelectedItems().clear();
notifyDataSetChanged();
}
}
\ No newline at end of file
package com.cneeds.rvhelpers.decoration;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.cneeds.rvhelpers.adapter.PinnedHeaderAdapter;
/**
* PinnedHeader对应的ItemDecoration,这里只是为了画悬浮标题,实际标题item不是用ItemDecoration实现的,是直接用Adapter里面的ItemView实现
*
* 参考博客:https://www.jianshu.com/p/1558cbd20d17
* https://blog.csdn.net/little762/article/details/79391807
* https://blog.csdn.net/briblue/article/details/70211942
*
* 参考github: https://github.com/tuacy/RecyclerPinnedHeader/blob/master/pinnedheader/src/main/java/com/tuacy/pinnedheader/PinnedHeaderItemDecoration.java
*
* author : maiqh
*/
public class PinnedHeaderItemDecoration extends RecyclerView.ItemDecoration {
/**
* 把要固定的View绘制在上层
*/
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
//确保是PinnedHeaderAdapter的adapter,确保有View
if (parent.getAdapter() instanceof PinnedHeaderAdapter && parent.getChildCount() > 0) {
PinnedHeaderAdapter adapter = (PinnedHeaderAdapter) parent.getAdapter();
View firstView = parent.getChildAt(0);
int firstAdapterPosition = parent.getChildAdapterPosition(firstView);
int pinnedHeaderPosition = getPinnedHeaderViewPosition(firstAdapterPosition, adapter);
if (pinnedHeaderPosition != -1) {
// 生成要固定的头部标题View
RecyclerView.ViewHolder pinnedHeaderViewHolder = adapter.onCreateViewHolder(parent,
adapter.getItemViewType(pinnedHeaderPosition));
adapter.onBindViewHolder(pinnedHeaderViewHolder, pinnedHeaderPosition);
View pinnedHeaderView = pinnedHeaderViewHolder.itemView;
// 确定粘性头部的宽高和坐标
ensurePinnedHeaderViewLayout(pinnedHeaderView, parent);
// 获取下一个标题与当前固定标题的偏移量
int sectionPinOffset = 0;
for (int index = 0; index < parent.getChildCount(); index++) {
if (adapter.isPinnedPosition(parent.getChildAdapterPosition(parent.getChildAt(index)))) {
View sectionView = parent.getChildAt(index);
int sectionTop = sectionView.getTop();
int pinViewHeight = pinnedHeaderView.getHeight();
if (sectionTop < pinViewHeight && sectionTop > 0) {
// sectionPinOffset是个负值
sectionPinOffset = sectionTop - pinViewHeight;
}
break;
}
}
// 重绘当前的粘性头部,实现粘性头部被定上去的效果
int saveCount = c.save();
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) pinnedHeaderView.getLayoutParams();
if (layoutParams == null) {
throw new NullPointerException("PinnedHeaderItemDecoration");
}
c.translate(layoutParams.leftMargin, sectionPinOffset);
c.clipRect(0, 0, parent.getWidth(), pinnedHeaderView.getMeasuredHeight()); // ?
// Manually render this view (and all of its children) to the given Canvas.
pinnedHeaderView.draw(c);
c.restoreToCount(saveCount);
}
}
}
/**
* 要给每个item设置间距主要靠这个函数来实现
*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
}
/**
* 根据第一个可见的adapter的位置去获取临近的一个要固定的position的位置(就是需要固定的标题在adapter的数据中的位置)
*
* @param adapterFirstVisible 第一个可见的adapter的位置
* @return -1:未找到 >=0 找到位置
*/
private int getPinnedHeaderViewPosition(int adapterFirstVisible, PinnedHeaderAdapter adapter) {
for (int index = adapterFirstVisible; index >= 0; index--) {
if (adapter.isPinnedPosition(index)) {
return index;
}
}
return -1;
}
private void ensurePinnedHeaderViewLayout(View pinView, RecyclerView recyclerView) {
if (pinView.isLayoutRequested()) {
/**
* 用的是RecyclerView的宽度测量,和RecyclerView的宽度一样
*/
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) pinView.getLayoutParams();
if (layoutParams == null) {
throw new NullPointerException("PinnedHeaderItemDecoration");
}
int widthSpec = View.MeasureSpec.makeMeasureSpec(
recyclerView.getMeasuredWidth() - layoutParams.leftMargin - layoutParams.rightMargin, View.MeasureSpec.EXACTLY);
int heightSpec;
if (layoutParams.height > 0) {
heightSpec = View.MeasureSpec.makeMeasureSpec(layoutParams.height, View.MeasureSpec.EXACTLY);
} else {
heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
pinView.measure(widthSpec, heightSpec);
pinView.layout(0, 0, pinView.getMeasuredWidth(), pinView.getMeasuredHeight());
}
}
}
package com.cneeds.rvhelpers.entity;
public class ContentBean {
private String title;
private String url;
public ContentBean(String url) {
this.url = url;
}
public ContentBean(String title, String url) {
this.title = title;
this.url = url;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
package com.cneeds.rvhelpers.entity;
public class HeaderBean implements IHeader {
private String title;
public HeaderBean(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment