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.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.cneeds.notouch.NoTouchConstant;
import com.cneeds.notouch.NoTouchListener;
import com.cneeds.notouch.NoTouchManager;
import com.cneeds.notouch.NoTouchParam;
import com.cneeds.notouch.bean.ActivityOperationBean;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.rvhelpers.CenterGridLayoutManager;
import com.cneeds.rvhelpers.helpers.KeyEventHelper;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
import com.cneeds.rvhelpers.decoration.PinnedHeaderItemDecoration;
import com.cneeds.rvhelpers.entity.ContentBean;
import com.cneeds.rvhelpers.entity.HeaderBean;
import com.cneeds.rvhelpers.helpers.SortDataHelper;
import java.util.ArrayList;
import java.util.List;
public class GridRecyclerActivity extends Activity implements NoTouchListener {
private RecyclerView mRvGrid;
private static final String TAG = "GridRecyclerActivity";
private CenterGridLayoutManager mLayoutManager;
private GridRecyclerAdapter<Object> mAdapter;
private ImageView mIvDelete;
private TextView mTvSelectAll;
private TextView mTvCancel;
private TextView mTvEdit;
private TextView mTvTitle;
private static final int SPAN_COUNT = 3;
private List mDataList;
public static void startUp(Context context) {
context.startActivity(new Intent(context, GridRecyclerActivity.class));
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_recycler);
mRvGrid = (RecyclerView) findViewById(R.id.recycler_grid);
NoTouchManager.getInstance().init(this);
// initAdapter(GridRecyclerActivity.this, mRvGrid, obtainData());
mDataList = obtainData2();
initAdapter(GridRecyclerActivity.this, mRvGrid, SortDataHelper.sortData(mDataList));
initBarView();
// handler.postDelayed(runnable, 1000);
}
private void initBarView() {
mIvDelete = (ImageView) findViewById(R.id.iv_delete);
mIvDelete.setVisibility(View.GONE);
mTvSelectAll = (TextView) findViewById(R.id.tv_select_all);
mTvSelectAll.setVisibility(View.GONE);
mTvCancel = (TextView) findViewById(R.id.tv_cancel);
mTvCancel.setVisibility(View.GONE);
mTvEdit = (TextView) findViewById(R.id.tv_edit);
mTvTitle = (TextView) findViewById(R.id.tv_title);
mTvEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.setEditMode(true);
mIvDelete.setVisibility(View.VISIBLE);
mTvSelectAll.setVisibility(View.VISIBLE);
mTvCancel.setVisibility(View.VISIBLE);
mTvEdit.setVisibility(View.GONE);
mTvTitle.setVisibility(View.INVISIBLE);
}
});
mTvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.setEditMode(false);
mIvDelete.setVisibility(View.GONE);
mTvSelectAll.setVisibility(View.GONE);
mTvCancel.setVisibility(View.GONE);
mTvEdit.setVisibility(View.VISIBLE);
mTvTitle.setVisibility(View.VISIBLE);
}
});
mTvSelectAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ("全不选".equals(mTvSelectAll.getText())) {
mAdapter.clearAllSelection();
mTvSelectAll.setText("全选");
} else {
mAdapter.selectAll();
mTvSelectAll.setText("全不选");
}
}
});
mIvDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//注意,如果是用SortDataHelper类,记得把原始的DataList里面的值也删掉,如下
mDataList.removeAll(mAdapter.getSelectedItems());
mAdapter.deleteSelected();
}
});
mAdapter.setOnSelectListener(new GridRecyclerAdapter.OnSelectListener() {
@Override
public void onSelect(View v, int position, boolean isChecked, List allSelectedItems, int contentItemCount) {
if (mTvSelectAll != null && mTvSelectAll.getVisibility() == View.VISIBLE) {
if (allSelectedItems != null && allSelectedItems.size() != contentItemCount) {
if ("全不选".equals(mTvSelectAll.getText())) {
mTvSelectAll.setText("全选");
}
} else {
if ("全选".equals(mTvSelectAll.getText())) {
mTvSelectAll.setText("全不选");
}
}
}
}
});
mAdapter.setOnItemClickListener(new GridRecyclerAdapter.OnItemClickListener() {
@Override
public void onItemClick(View v, int position) {
Toast.makeText(v.getContext(), "点击了" + position, Toast.LENGTH_SHORT).show();
}
});
}
private void initAdapter(Context context, RecyclerView recyclerView, final List<Object> dataList) {
mAdapter = new GridRecyclerAdapter<>(dataList, SPAN_COUNT);
mLayoutManager = new CenterGridLayoutManager(context, SPAN_COUNT, mAdapter);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(mAdapter);
recyclerView.addItemDecoration(new PinnedHeaderItemDecoration());
// 解决notifyItemChanged闪烁问题:参考:https://blog.csdn.net/u014537423/article/details/52777978
recyclerView.getItemAnimator().setSupportsChangeAnimations(false);
}
@Override
public ActivityOperationBean onSelectedChange(CoordinateBean coordinateBean) {
ActivityOperationBean activityOperationBean = new ActivityOperationBean();
int x = coordinateBean.getX();
if (coordinateBean.getY() == 0 && !outOfFirstBound(coordinateBean)) {
handleKeyEvent(coordinateBean, activityOperationBean);
if (activityOperationBean.getOperationResult() == NoTouchConstant.OperationResult.SUCCESS) {
if (mAdapter.getCurrentHighLightPosition() != GridRecyclerAdapter.NONE_SELECT) {
mAdapter.setCurrentHighLight(GridRecyclerAdapter.NONE_SELECT);
}
}
} else {
clearHighlight();
mCurrentHighlightView = null;
if (mAdapter != null) {
KeyEventHelper.PositionBean positionBean = mAdapter.moveToNext(coordinateBean.getX(), coordinateBean.getY() - 1);
coordinateBean.setY(positionBean.getY() + 1);
coordinateBean.setX(positionBean.getX());
int adapterPosition = positionBean.getAdapterPosition();
if (adapterPosition >= 0) {
mRvGrid.smoothScrollToPosition(adapterPosition);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
} else {
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.FAIL);
}
}
}
return activityOperationBean;
}
@Override
public ActivityOperationBean onSelectedEnter(CoordinateBean coordinateBean) {
ActivityOperationBean activityOperationBean = new ActivityOperationBean();
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
View view = mAdapter.getHighLightView();
if (view != null) {
view.callOnClick();
}
if (mCurrentHighlightView != null) {
mCurrentHighlightView.callOnClick();
handleKeyEvent(coordinateBean, activityOperationBean);
}
return activityOperationBean;
}
@Override
public ActivityOperationBean onSelectNone() {
Log.d(TAG, "onSelectNone");
ActivityOperationBean activityOperationBean = new ActivityOperationBean();
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
if (mAdapter != null && mAdapter.getCurrentHighLightPosition() != GridRecyclerAdapter.NONE_SELECT) {
mAdapter.setCurrentHighLight(GridRecyclerAdapter.NONE_SELECT);
} else {
// 清除顶部按钮的选中状态
clearHighlight();
}
return activityOperationBean;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
Log.d(TAG, "dispatchKeyEvent Action : " + event.getAction());
if (event.getAction() == KeyEvent.ACTION_UP) {
if (NoTouchManager.getInstance().checkUseKeyCode(event.getKeyCode())) {
NoTouchManager.getInstance().onKeyDown(event.getKeyCode(), event);
}
}
int code = event.getKeyCode();
if (code == KeyEvent.KEYCODE_SOFT_RIGHT || code == KeyEvent.KEYCODE_SOFT_LEFT || code == KeyEvent.KEYCODE_DPAD_LEFT
|| code == KeyEvent.KEYCODE_DPAD_UP || code == KeyEvent.KEYCODE_DPAD_RIGHT || code == KeyEvent.KEYCODE_DPAD_DOWN
|| code == KeyEvent.KEYCODE_ENTER) {
return true;
}
return super.dispatchKeyEvent(event);
}
private View mCurrentHighlightView;
private void handleKeyEvent(CoordinateBean coordinateBean, ActivityOperationBean activityOperationBean) {
if (mTvEdit.getVisibility() == View.VISIBLE && coordinateBean.getX() == 0) {
setHighlight(mTvEdit);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
} else if (mTvCancel.getVisibility() == View.VISIBLE) {
switch (coordinateBean.getX()) {
case 0:
setHighlight(mTvCancel);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
break;
case 1:
setHighlight(mTvSelectAll);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
break;
case 2:
setHighlight(mIvDelete);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
break;
default:
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.FAIL);
break;
}
} else {
coordinateBean.setX(0);
coordinateBean.setY(0);
setHighlight(mTvEdit);
activityOperationBean.setOperationResult(NoTouchConstant.OperationResult.SUCCESS);
}
}
private void clearHighlight() {
if (mTvEdit.getBackground() != null) {
mTvEdit.setBackground(null);
}
if (mTvCancel.getBackground() != null) {
mTvCancel.setBackground(null);
}
if (mTvSelectAll.getBackground() != null) {
mTvSelectAll.setBackground(null);
}
if (mIvDelete.getBackground() != null) {
mIvDelete.setBackground(null);
}
}
private void setHighlight(View view) {
clearHighlight();
Drawable drawable = getResources().getDrawable(R.drawable.rect_solid_border_ff4242_1px);
view.setBackground(drawable);
mCurrentHighlightView = view;
}
/**
* 用于处理标题栏光标到了最右边再往右的情况
* 注意:标题栏有更改的时候,一定要改这里
* @param coordinateBean
* @return true: 光标向右动作超出标题栏, false: 光标向右没有超出标题栏
*/
private boolean outOfFirstBound(CoordinateBean coordinateBean) {
if (mTvEdit.getVisibility() == View.VISIBLE && coordinateBean.getX() > 0) {
coordinateBean.setX(0);
coordinateBean.setY(1);
return true;
} else if (mTvCancel.getVisibility() == View.VISIBLE && coordinateBean.getX() > 2) {
coordinateBean.setX(0);
coordinateBean.setY(1);
return true;
}
return false;
}
@Override
protected void onResume() {
super.onResume();
NoTouchParam.Builder builder = new NoTouchParam.Builder();
builder.setSpecialFlag(NoTouchConstant.SpecialFlag.SINGLE_LEVEL_FLAG);
NoTouchManager.getInstance().registerNoTouchListener(this, builder.build());
}
@Override
protected void onPause() {
super.onPause();
NoTouchManager.getInstance().unRegisterNoTouchListener(this);
}
private List<Object> obtainData() {
List<Object> list = new ArrayList<>();
list.add(new HeaderBean("2016年12月01日"));
list.add(new ContentBean("http://pic.wenwen.soso.com/p/20130907/20130907174128-2028703867.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月02日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月03日"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月04日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月05日"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
// list.add("2016-07-24");
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月06日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
// list.add("2016-07-25");
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月07日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
// list.add("2016-07-26");
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
// list.add("2016-07-27");
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月08日"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new ContentBean("http://pic.wenwen.soso.com/p/20130907/20130907174128-2028703867.jpg"));
list.add(new HeaderBean("2016年12月09日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
// list.add("2016-07-29");
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
// list.add("2016-07-30");
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3790810349,4012335838&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3781123768,373023027&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月10日"));
list.add(new ContentBean("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4052445718,1344904722&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1730874133,3861130981&fm=27&gp=0.jpg"));
list.add(new ContentBean("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4117837678,3129898700&fm=27&gp=0.jpg"));
list.add(new HeaderBean("2016年12月11日"));
list.add(new ContentBean("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1960816299,803825902&fm=27&gp=0.jpg"));
return list;
}
private List<ContentBean> obtainData2() {
List<ContentBean> list = new ArrayList<>();
list.add(new ContentBean("2016年12月11日", ""));
list.add(new ContentBean("2016年12月11日", ""));
list.add(new ContentBean("2016年12月11日", ""));
list.add(new ContentBean("2016年12月12日", ""));
list.add(new ContentBean("2016年12月12日", ""));
list.add(new ContentBean("2016年12月12日", ""));
list.add(new ContentBean("2016年12月13日", ""));
list.add(new ContentBean("2016年12月13日", ""));
list.add(new ContentBean("2016年12月13日", ""));
list.add(new ContentBean("2016年12月13日", ""));
list.add(new ContentBean("2016年12月14日", ""));
list.add(new ContentBean("2016年12月14日", ""));
list.add(new ContentBean("2016年12月14日", ""));
list.add(new ContentBean("2016年12月15日", ""));
list.add(new ContentBean("2016年12月15日", ""));
list.add(new ContentBean("2016年12月16日", ""));
list.add(new ContentBean("2016年12月17日", ""));
list.add(new ContentBean("2016年12月17日", ""));
list.add(new ContentBean("2016年12月17日", ""));
list.add(new ContentBean("2016年12月17日", ""));
list.add(new ContentBean("2016年12月18日", ""));
list.add(new ContentBean("2016年12月18日", ""));
list.add(new ContentBean("2016年12月18日", ""));
list.add(new ContentBean("2016年12月19日", ""));
list.add(new ContentBean("2016年12月19日", ""));
list.add(new ContentBean("2016年12月19日", ""));
list.add(new ContentBean("2016年12月20日", ""));
list.add(new ContentBean("2016年12月20日", ""));
list.add(new ContentBean("2016年12月20日", ""));
list.add(new ContentBean("2016年12月21日", ""));
list.add(new ContentBean("2016年12月21日", ""));
list.add(new ContentBean("2016年12月21日", ""));
list.add(new ContentBean("2016年12月22日", ""));
list.add(new ContentBean("2016年12月22日", ""));
list.add(new ContentBean("2016年12月23日", ""));
list.add(new ContentBean("2016年12月24日", ""));
list.add(new ContentBean("2016年12月24日", ""));
list.add(new ContentBean("2016年12月25日", ""));
return list;
}
private Handler handler = new Handler();
//写在 onCreate() 的外面
Runnable runnable = new Runnable() {
@Override
public void run() {
/**
逻辑代码写在这
**/
mDataList.add(new ContentBean("2016年12月10日", ""));
List list = SortDataHelper.sortData(mDataList);
mAdapter.setDataList(list);
//这个好像才是执行周期的时间(单位:ms)
handler.postDelayed(this, 3000);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
}
}
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 android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.view.KeyEvent;
import com.cneeds.notouch.bean.ActivityOperationBean;
import com.cneeds.notouch.bean.CoordinateBean;
import com.cneeds.notouch.bean.OperationBean;
import com.cneeds.notouch.operation.NoTouchOperation;
import com.cneeds.notouch.operation.NoTouchOperationFactory;
import java.util.HashMap;
import static com.cneeds.notouch.NoTouchConstant.ColumnName.COLUMN_FOCUS_KEY;
import static com.cneeds.notouch.NoTouchConstant.ColumnName.COLUMN_FOCUS_NAME;
import static com.cneeds.notouch.NoTouchConstant.ColumnName.COLUMN_FOCUS_NEED;
import static com.cneeds.notouch.NoTouchConstant.ColumnName.COLUMN_FOCUS_STATE;
import static com.cneeds.notouch.NoTouchConstant.ColumnName.COLUMN_FOCUS_TEMP;
import static com.cneeds.notouch.NoTouchConstant.Focus.APP_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.Focus.SYSTEM_BAR_FOCUS;
import static com.cneeds.notouch.NoTouchConstant.FocusStatus.RECOVER;
import static com.cneeds.notouch.NoTouchConstant.OperationResult.SUCCESS;
/**
* 非触控的管理类,主要做一些非触控的逻辑操作
* @author zhany
*/
public class NoTouchFocusController {
private Uri CONTENT_URI = null;
private Uri NEED_FOCUS_URL = null;
private NoTouchListener mNoTouchListener;
private NoTouchOperation mNoTouchOperation;
private OperationHandler mOperationHandler;
private Context mContext;
private final int MESSAGE_KEY_DOWN = 1;
private final int MESSAGE_UPDATE_FOCUS = 2;
private final int MESSAGE_DELAYED = 600;
private int mCurrentFocus = SYSTEM_BAR_FOCUS;
private int mNavigationBarKeyCode;
private NoTouchActivityOperation mNoTouchActivityOperation;
private NoTouchSelfListener mNoTouchSelfListener;
private HashMap<String, NoTouchOperation> mNoTouchOperationCache;
private int mAppLastKeyCode;
private boolean mSupportHardKey = false;
protected NoTouchFocusController(Context context){
try {
mContext = context;
mNoTouchOperationCache = new HashMap<>();
mOperationHandler = new OperationHandler(Looper.getMainLooper());
mNoTouchActivityOperation = new NoTouchActivityOperation();
CONTENT_URI = Uri.parse(NoTouchConstant.FOCUS_STATUS_URL);
NEED_FOCUS_URL = Uri.parse(NoTouchConstant.FOCUS_NEED_URL);
mContext.getContentResolver().registerContentObserver(CONTENT_URI, false, mNoTouchFocusObserver);
} catch (Exception e) {
e.printStackTrace();
}
}
public void registerSelfListener(NoTouchSelfListener selfListener){
updateCurrentFocus();
sendCurrentNeedFocus(true);
mNoTouchSelfListener = selfListener;
mNoTouchSelfListener.onFocusChange(mCurrentFocus);
mNoTouchListener = null;
}
public void unRegisterSelfListener(NoTouchSelfListener selfListener){
if(mNoTouchSelfListener != null
&& selfListener != null
&& mNoTouchSelfListener.equals(selfListener)){
sendCurrentNeedFocus(false);
mNoTouchSelfListener = null;
}
}
private ContentObserver mNoTouchFocusObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateCurrentFocus();
if(mNoTouchSelfListener != null){
mNoTouchSelfListener.onFocusChange(mCurrentFocus);
}
if(mCurrentFocus == APP_FOCUS && mNoTouchOperation != null){
if(mNavigationBarKeyCode == KeyEvent.KEYCODE_SOFT_RIGHT){
mNoTouchOperation.resetInitCoordinate();
}
mNoTouchOperation.restoreLastCoordinate();
}else if(mNoTouchListener != null){
mNoTouchListener.onSelectNone();
}
}
};
public void registerNoTouchTempListener(String packageName){
try {
NoTouchLog.d("registerNoTouchTempListener = " + packageName);
ContentValues values = new ContentValues();
values.put(COLUMN_FOCUS_NAME, packageName + ":" + Process.myPid());
values.put(COLUMN_FOCUS_TEMP, true);
values.put(COLUMN_FOCUS_NEED, true);
mContext.getContentResolver().update(NEED_FOCUS_URL, values, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void unRegisterNoTouchTempListener(String packageName){
NoTouchLog.d("unRegisterNoTouchTempListener = " + packageName);
try{
ContentValues values = new ContentValues();
values.put(COLUMN_FOCUS_NAME, packageName + ":" + Process.myPid());
values.put(COLUMN_FOCUS_TEMP, true);
values.put(COLUMN_FOCUS_NEED, false);
mContext.getContentResolver().update(NEED_FOCUS_URL, values, null, null);
}catch (Exception e){
e.printStackTrace();
}
}
public void registerNoTouchListener(NoTouchListener listener, NoTouchParam param){
mOperationHandler.removeCallbacksAndMessages(null);
mNoTouchListener = listener;
mNoTouchSelfListener = null;
sendCurrentNeedFocus(true);
boolean isCache = false;
if(param.getClassName() != null && param.getFocusStatus() == RECOVER){
mNoTouchOperation = mNoTouchOperationCache.get(param.getClassName());
isCache = true;
}else{
mNoTouchOperation = null;
}
if(mNoTouchOperation == null){
mNoTouchOperation = NoTouchOperationFactory.createOperation(param);
mNoTouchOperationCache.put(param.getClassName(), mNoTouchOperation);
}
mNoTouchOperation.registerActivityOperationResult(mNoTouchActivityOperation);
if(param.getNoNavigationBar()){
sendCurrentHasFocus();
}
mNoTouchListener.onSelectNone();
Message message = mOperationHandler.obtainMessage(MESSAGE_UPDATE_FOCUS);
message.obj = isCache;
mOperationHandler.sendMessageDelayed(message, MESSAGE_DELAYED);
if(mNoTouchOperation == null){
try {
throw new NullPointerException("NoTouchFocusController mNoTouchOperation IS NULL");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void unRegisterNoTouchListener(NoTouchListener listener){
if(mNoTouchListener != null && listener != null
&& mNoTouchListener.equals(listener)){
mNoTouchListener = null;
mOperationHandler.removeCallbacksAndMessages(null);
sendCurrentNeedFocus(false);
}
}
public void onKeyDown(int keyCode, KeyEvent keyEvent){
checkSupportHardKey(keyCode);
mAppLastKeyCode = keyCode;
Message message = mOperationHandler.obtainMessage();
message.what = MESSAGE_KEY_DOWN;
message.arg1 = keyCode;
message.obj = keyEvent;
message.sendToTarget();
}
private void checkSupportHardKey(int keyCode){
if(mSupportHardKey){
return;
}
mSupportHardKey = checkUseKeyCode(keyCode);
}
public boolean checkUseKeyCode(int keyCode){
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_UP
|| keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN
|| keyCode == KeyEvent.KEYCODE_SOFT_LEFT
|| keyCode == KeyEvent.KEYCODE_SOFT_RIGHT
|| keyCode == KeyEvent.KEYCODE_ENTER
|| keyCode == NoTouchConstant.INIT_KEY_CODE){
return true;
}
return false;
}
public boolean getSupportHardKey(){
return mSupportHardKey;
}
/**
* 取消焦点,将当前焦点移交到statusbar上
*/
public void cancelFocus(){
try {
ContentValues values = new ContentValues();
values.put(COLUMN_FOCUS_STATE, SYSTEM_BAR_FOCUS);
values.put(COLUMN_FOCUS_KEY, mAppLastKeyCode);
mContext.getContentResolver().update(CONTENT_URI, values, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 更新当前的焦点是在APP中还是在statusbar中
*/
private void updateCurrentFocus(){
Cursor cursor = null;
try {
cursor = mContext.getContentResolver().query(CONTENT_URI, null, null, null ,null);
if(cursor != null && cursor.moveToFirst()){
mCurrentFocus = cursor.getInt(cursor.getColumnIndex(COLUMN_FOCUS_STATE));
mNavigationBarKeyCode = cursor.getInt(cursor.getColumnIndex(COLUMN_FOCUS_KEY));
NoTouchLog.d("mCurrentFocus = " + mCurrentFocus);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(cursor != null){
cursor.close();
}
}
}
/**
* 设置当前APP需要焦点,可以进行触控操作
* @param needFocus
*/
private void sendCurrentNeedFocus(boolean needFocus){
try {
NoTouchLog.d("sendCurrentNeedFocus");
ContentValues values = new ContentValues();
values.put(COLUMN_FOCUS_NAME, mContext.getPackageName() + ":" + Process.myPid());
values.put(COLUMN_FOCUS_NEED, needFocus);
values.put(COLUMN_FOCUS_TEMP, false);
mContext.getContentResolver().update(NEED_FOCUS_URL, values, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置当前APP获取焦点
*/
private void sendCurrentHasFocus(){
try {
ContentValues values = new ContentValues();
values.put(COLUMN_FOCUS_STATE, APP_FOCUS);
values.put(COLUMN_FOCUS_KEY, mAppLastKeyCode);
mContext.getContentResolver().update(CONTENT_URI, values, null, new String[]{COLUMN_FOCUS_STATE});
mCurrentFocus = APP_FOCUS;
} catch (Exception e) {
e.printStackTrace();
}
}
private class OperationHandler extends Handler{
public OperationHandler(Looper looper){
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MESSAGE_KEY_DOWN:
if(mCurrentFocus == SYSTEM_BAR_FOCUS){
return;
}
if(mNoTouchOperation != null){
mNoTouchOperation.operation(msg.arg1, (KeyEvent) msg.obj);
}
break;
case MESSAGE_UPDATE_FOCUS:{
updateCurrentFocus();
boolean isCached = (boolean) msg.obj;
if(isCached && mCurrentFocus == APP_FOCUS && mSupportHardKey){
mNoTouchOperation.restoreLastCoordinate();
}else if(mCurrentFocus == APP_FOCUS){
onKeyDown(NoTouchConstant.INIT_KEY_CODE, null);
}
}
break;
default:
break;
}
}
}
private class NoTouchActivityOperation implements ActivityOperationListener{
@Override
public ActivityOperationBean activityOperation(OperationBean operationBean) {
ActivityOperationBean result = new ActivityOperationBean();
NoTouchLog.d("activityOperation: mNoTouchListener=" + mNoTouchListener + ", operationBean=" + operationBean);
if(mNoTouchListener != null && operationBean != null){
switch (operationBean.getOperationFlag()){
case NoTouchConstant.OperationFlag.OPERATION_NONE:
result.setOperationResult(SUCCESS);
break;
case NoTouchConstant.OperationFlag.OPERATION_NO_FOCUS:
cancelFocus();
result = mNoTouchListener.onSelectNone();
break;
case NoTouchConstant.OperationFlag.OPERATION_SELECTED:
result = mNoTouchListener.onSelectedChange(operationBean.getCoordinateBean());
break;
case NoTouchConstant.OperationFlag.OPERATION_ENTER:
result = mNoTouchListener.onSelectedEnter(operationBean.getCoordinateBean());
break;
default:
break;
}
}
return result;
}
}
public void setRecoverCoordinateBean(String className, CoordinateBean coordinateBean){
if(mNoTouchOperationCache != null && className != null){
NoTouchOperation noTouchOperation = mNoTouchOperationCache.get(className);
if(noTouchOperation != null){
noTouchOperation.setLastCoordinate(coordinateBean);
}
}
}
public interface ActivityOperationListener{
ActivityOperationBean activityOperation(OperationBean operationBean);
}
}
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.NoTouchConstant;
import com.cneeds.notouch.NoTouchParam;
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.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.MIN_VALID_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.NONE_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.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;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class DoubleLevelHorizontalOperation extends AbsNoTouchOperation{
private int LEVEL_0_MIN_VALUE = 1;
private int LEVEL_1_MIN_VALUE = 0;
protected DoubleLevelHorizontalOperation(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();
coordinateBean.setX(LEVEL_1_MIN_VALUE);
coordinateBean.setY(LEVEL_1_MIN_VALUE);
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_ONE:{
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_TWO:{
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_THIRD:{
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_FOUR:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}else{
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_ONE:{
operationBean.getCoordinateBean().setXx(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_TWO:{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_THIRD:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
switch (getFailCount()){
case FAIL_NONE:{
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.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
break;
default:
break;
}
}else{
if(operationBean.getCoordinateBean().getXx() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getYy() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setXx(MAX_VALUE);
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
}
private void enterKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
operationBean.setOperationFlag(OPERATION_ENTER);
}else{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
private void downKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
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;
}
}else{
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
}
private void rightKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
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;
}
}else{
switch (getFailCount()){
case FAIL_NONE:{
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case FAIL_ONE:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
}
}
}
private void upKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
switch (getFailCount()){
case FAIL_NONE:{
if(operationBean.getCoordinateBean().getY() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
break;
case NoTouchConstant.OperationFailCount.FAIL_ONE:{
operationBean.getCoordinateBean().setX(MAX_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
default:
break;
}
}else{
if(operationBean.getCoordinateBean().getYy() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
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);
}
}else{
if(operationBean.getCoordinateBean().getXx() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
}
}
package com.cneeds.notouch.operation;
import android.view.KeyEvent;
import com.cneeds.notouch.NoTouchConstant;
import com.cneeds.notouch.NoTouchFocusController;
import com.cneeds.notouch.NoTouchParam;
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.MAX_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.MIN_VALID_VALUE;
import static com.cneeds.notouch.NoTouchConstant.OperationConstant.NONE_VALUE;
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;
import static com.cneeds.notouch.NoTouchConstant.OperationFlag.OPERATION_SELECTED;
public class DoubleLevelVerticalOperation extends AbsNoTouchOperation{
private int LEVEL_0_MIN_VALUE = 1;
private int LEVEL_1_MIN_VALUE = 0;
protected DoubleLevelVerticalOperation(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();
coordinateBean.setX(LEVEL_1_MIN_VALUE);
coordinateBean.setY(LEVEL_1_MIN_VALUE);
operationBean.setCoordinateBean(coordinateBean);
operationBean.setOperationFlag(OPERATION_SELECTED);
return operationBean;
}
private void shiftRightKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
switch (getFailCount()){
case NoTouchConstant.OperationFailCount.FAIL_NONE:{
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_ONE:{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_TWO:{
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_THIRD:{
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_FOUR:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}else{
switch (getFailCount()){
case NoTouchConstant.OperationFailCount.FAIL_NONE:{
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_ONE:{
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
break;
case NoTouchConstant.OperationFailCount.FAIL_TWO:{
operationBean.setOperationFlag(OPERATION_NONE);
}
break;
default:
break;
}
}
}
private void shiftLeftKeyEvent(OperationBean operationBean) {
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
switch (getFailCount()){
case NoTouchConstant.OperationFailCount.FAIL_NONE:{
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.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
break;
default:
break;
}
}else{
if(operationBean.getCoordinateBean().getXx() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setXx(operationBean.getCoordinateBean().getXx() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else if(operationBean.getCoordinateBean().getYy() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NO_FOCUS);
}
}
}
private void enterKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
operationBean.setOperationFlag(OPERATION_ENTER);
}else{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
private void downKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
private void rightKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() + 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.getCoordinateBean().setX(LEVEL_0_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_0_MIN_VALUE);
operationBean.setOperationFlag(OPERATION_SELECTED);
}
}
private void upKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
if(operationBean.getCoordinateBean().getY() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setY(operationBean.getCoordinateBean().getY() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}else{
if(operationBean.getCoordinateBean().getYy() > LEVEL_1_MIN_VALUE){
operationBean.getCoordinateBean().setYy(operationBean.getCoordinateBean().getYy() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.setOperationFlag(OPERATION_NONE);
}
}
}
private void leftKeyEvent(OperationBean operationBean) {
if(getFailCount() == 1){
operationBean.setOperationFlag(OPERATION_NONE);
return;
}
if(getCoordinateLevel(operationBean.getCoordinateBean()) == LEVEL_0){
if(operationBean.getCoordinateBean().getX() > LEVEL_0_MIN_VALUE){
operationBean.getCoordinateBean().setX(operationBean.getCoordinateBean().getX() - 1);
operationBean.setOperationFlag(OPERATION_SELECTED);
}else{
operationBean.getCoordinateBean().setX(LEVEL_1_MIN_VALUE);
operationBean.getCoordinateBean().setY(LEVEL_1_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.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;
import android.view.View;
import android.view.ViewGroup;
import com.cneeds.rvhelpers.entity.IHeader;
import com.cneeds.rvhelpers.helpers.KeyEventHelper;
import com.cneeds.rvhelpers.viewholder.BaseViewHolder;
import com.cneeds.rvhelpers.viewholder.ContentHolder;
import com.cneeds.rvhelpers.viewholder.TitleHolder;
import java.util.ArrayList;
import java.util.List;
/**
* 参考博客:https://www.jianshu.com/p/1558cbd20d17
* https://blog.csdn.net/little762/article/details/79391807
* https://blog.csdn.net/briblue/article/details/70211942
* <p>
* 参考github: https://github.com/tuacy/RecyclerPinnedHeader/blob/02ea221444a6b4810c49c158fb0930d87bd59906/app/src/main/java/com/tuacy/recyclerpinnedheader/grid/GridRecyclerAdapter.java
* <p>
* author : maiqh
*/
public class GridRecyclerAdapter<T extends Object> extends PinnedHeaderAdapter<BaseViewHolder> {
protected static final int VIEW_TYPE_ITEM_HEADER = 0;
protected static final int VIEW_TYPE_ITEM_CONTENT = 1;
public static final int NONE_SELECT = -1;
private List<T> mDataList;
private int mHighListPosition = NONE_SELECT;
private View mHighListItemView;
private final KeyEventHelper mKeyEventHelper;
private boolean mEditMode;
private OnSelectListener mOnSelectListener;
private OnItemClickListener mOnItemClickListener;
/**
* @param dataList
* @param spanCount The number of columns in the grid
*/
public GridRecyclerAdapter(List<T> dataList, int spanCount) {
if (dataList == null) {
mDataList = new ArrayList<>();
} else {
mDataList = dataList;
}
mKeyEventHelper = new KeyEventHelper(dataList, spanCount);
registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
// 监听数据数据是否变化,如果有变化会及时更新坐标二维表
mKeyEventHelper.resetCoordination(mDataList);
}
});
}
public void setDataList(List<T> dataList) {
if (dataList == null) {
mDataList = new ArrayList<>();
} else {
mDataList = dataList;
}
notifyDataSetChanged();
}
public List getDataList() {
if (mDataList == null) {
mDataList = new ArrayList<>();
}
return mDataList;
}
public int getAdapterPosition(int x, int y) {
return mKeyEventHelper.getAdapterPosition(x, y);
}
/**
* 移动到下一位置, 用于响应实体按键/旋钮的控制
*
* @param x 外界要求移动到的x轴位置
* @param y 外界要求移动到的y轴位置
* @return 返回的PositionBean 包含xy实际会移动到的位置,和对应成员的adapter位置
*/
public KeyEventHelper.PositionBean moveToNext(int x, int y) {
// 防止异常情况导致crash
if (x < 0) x = 0;
if (y < 0) y = 0;
KeyEventHelper.PositionBean positionBean = mKeyEventHelper.moveToNext(x, y, mHighListPosition);
if (positionBean.getAdapterPosition() >= 0) {
setCurrentHighLight(positionBean.getAdapterPosition());
}
return positionBean;
}
/**
* 获取当前高亮item的位置,注意:默认值是-1 GridRecyclerAdapter.NONE_SELECT
* @return
*/
public int getCurrentHighLightPosition() {
return mHighListPosition;
}
public View getHighLightView() {
if (mHighListPosition == NONE_SELECT) {
mHighListItemView = null;
}
return mHighListItemView;
}
public void setHighListItemView(View view) {
mHighListItemView = view;
}
/**
* 设置高亮的item, 用于响应实体按键/旋钮的控制
*
* @param highListPosition 高亮位置
* @return 高亮位置
*/
public int setCurrentHighLight(int highListPosition) {
if (highListPosition < 0) {
mHighListPosition = NONE_SELECT;
mHighListItemView = null;
} else if (getDataList().size() > mHighListPosition) {
T t = mDataList.get(highListPosition);
if (t instanceof IHeader) {
// 跳过标题
if (mHighListPosition > highListPosition) {
mHighListPosition = highListPosition - 1;
} else {
mHighListPosition = highListPosition + 1;
}
} else {
mHighListPosition = highListPosition;
}
} else {
mHighListPosition = mDataList.size() - 1;
}
notifyDataSetChanged();
return mHighListPosition;
}
public boolean getEditMode() {
return mEditMode;
}
/**
* 把选中的类删除
*/
public void deleteSelected() {
List<T> selectedItems = getSelectedItems();
// 删除选中的数据
for (int i = 0; i < selectedItems.size(); i++) {
T t1 = selectedItems.get(i);
if (!getDataList().contains(t1)) {
break;
}
int index = mDataList.indexOf(t1);
boolean remove = mDataList.remove(t1);
if (remove) {
// 下面处理标题的删除,注意:下面的index对应的不再是被删除的数据
if (mDataList.size() <= index) {
// 删除了最后一个
T t = mDataList.get(mDataList.size() - 1);
if (t instanceof IHeader) {
// 如果最后一个是标题,就把它删除
mDataList.remove(mDataList.size() - 1);
}
} else if (index > 0) { // 第一个是标题,index理论上不会为0,这里加个判断预防万一
T t = mDataList.get(index);
T previousT = mDataList.get(index - 1);
// 如果连续两个都是标题,就把第一个标题删除
if (t instanceof IHeader && previousT instanceof IHeader) {
mDataList.remove(index - 1);
}
}
}
}
clearAllSelection();
}
/**
* select all items
*/
public void selectAll() {
getSelectedItems().clear();
for (int i = 0; i < getDataList().size(); i++) {
T t = mDataList.get(i);
if (!(t instanceof IHeader)) {
getSelectedItems().add(t);
}
}
notifyDataSetChanged();
}
/**
* 设置编辑模式
*
* @param editMode true: 编辑模式, false:非编辑模式
*/
public void setEditMode(boolean editMode) {
mEditMode = editMode;
if (!mEditMode) {
clearAllSelection();
}
notifyDataSetChanged();
}
/**
* 切换选中/未选中
*
* @param view 被点击的itemView
* @param position 被点击的itemView的位置
* @param contentBean 被点击的itemView的数据bean
*/
public void toggleSelection(View view, int position, Object contentBean) {
boolean isChecked = toggleSelection(position, contentBean);
if (mOnSelectListener != null) {
mOnSelectListener.onSelect(view, position, isChecked, getSelectedItems(), mKeyEventHelper.getTotalCount());
}
}
public void clickItem(View view, int position) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view, position);
}
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM_HEADER) {
return new TitleHolder(parent.getContext(), parent);
} else {
return new ContentHolder(parent.getContext(), parent);
}
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.bindData(getDataList().get(position), position, GridRecyclerAdapter.this);
}
@Override
public int getItemCount() {
return mDataList == null ? 0 : mDataList.size();
}
@Override
public int getItemViewType(int position) {
if (getDataList().get(position) instanceof IHeader) {
return VIEW_TYPE_ITEM_HEADER;
} else {
return VIEW_TYPE_ITEM_CONTENT;
}
}
@Override
public boolean isPinnedPosition(int position) {
return getItemViewType(position) == VIEW_TYPE_ITEM_HEADER;
}
public interface OnSelectListener {
/**
* 选择回调
*
* @param v 当前被点击的view
* @param adapterPosition 当前被点击的位置
* @param isChecked true:选择, false:取消选择
* @param allSelectedItems 已经勾选的item
* @param contentItemCount 除标题item外,全部item总数
*/
void onSelect(View v, int adapterPosition, boolean isChecked, List allSelectedItems, int contentItemCount);
}
public void setOnSelectListener(OnSelectListener onSelectListener) {
mOnSelectListener = onSelectListener;
}
public interface OnItemClickListener {
/**
* 选择回调
*
* @param v 当前被点击的view
* @param adapterPosition 当前被点击的位置
*/
void onItemClick(View v, int adapterPosition);
}
public void setOnItemClickListener(OnItemClickListener onSelectListener) {
mOnItemClickListener = onSelectListener;
}
}
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;
}
}
package com.cneeds.rvhelpers.entity;
public interface IHeader {
}
package com.cneeds.rvhelpers.helpers;
import com.cneeds.rvhelpers.entity.IHeader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 按键/旋钮事件处理
* author: maiqh
*/
public class KeyEventHelper {
// 存储"坐标"对应"adapter position"的二维表结构,
private ArrayList<ArrayList<Integer>> mCoordinationList;
public final static int ERROR_POSITION = -1;
// 存储"adapter position"对应"坐标"的map缓存
private HashMap<Integer, KeyEventHelper.PositionBean> mPositionMap;
// The number of columns in the grid
protected int mSpanCount;
// 缓存原始数据,用于判断需不需要更新坐标二维表
private ArrayList mTempArrayList = new ArrayList();
public KeyEventHelper(List<?> dataList, int spanCount) {
mCoordinationList = new ArrayList<>();
mPositionMap = new HashMap<>();
mSpanCount = spanCount;
resetCoordination(dataList);
}
public void resetCoordination(List<?> dataList) {
if (dataList == null || mTempArrayList.equals(dataList)) {
return;
}
mCoordinationList.clear();
mPositionMap.clear();
mTempArrayList.clear();
Object lastO = null;
for (int i = 0; i < dataList.size(); i++) {
Object currentO = dataList.get(i);
// 把position转换为坐标二维表
convert2Coordination(currentO, lastO, i);
lastO = currentO;
mTempArrayList.add(currentO);
}
}
/**
* 把GridLayout的网格布局记录为一个坐标二维表
*
* @param currentT 当前元素
* @param lastT 上一个记录的元素
* @param adapterPosition 当前元素对应的Adapter位置
*/
private void convert2Coordination(Object currentT, Object lastT, Integer adapterPosition) {
if (currentT instanceof IHeader) {
// 标题不记录
return;
}
int size = mCoordinationList.size();
// 非第一行 && 当前行不满最大列数 && 上一个item非标题
if (size > 0 && mCoordinationList.get(size - 1).size() < mSpanCount && !(lastT instanceof IHeader)) {
// 记录位置
mCoordinationList.get(size - 1).add(adapterPosition);
} else {
// (第一行 || 当前行满最大列数 || 上一个item非标题) 满足这个三个条件其中一个都新建一行
ArrayList<Integer> newColumnList = new ArrayList<>();
newColumnList.add(adapterPosition);
mCoordinationList.add(newColumnList);
}
// 记录position为key,对应的XY为Value的map
mPositionMap.put(adapterPosition, new KeyEventHelper.PositionBean(mCoordinationList.get(mCoordinationList.size() - 1).size() - 1, mCoordinationList.size() - 1, adapterPosition));
}
/**
* 获取当前第x列,第y行的元素的adapter位置(adapter的数据包含标题)
*
* @param x 第x列
* @param y 第y行
* @return 元素在adapter中的位置, 如果不存在就返回 {@BaseGridRecyclerAdapter.NONE_SELECT}
*/
public int getAdapterPosition(int x, int y) {
if (mCoordinationList.size() <= y || y < 0) {
return ERROR_POSITION;
}
ArrayList<Integer> rowList = mCoordinationList.get(y);
if (rowList == null || rowList.size() <= x) {
return ERROR_POSITION;
}
Integer columnCount = rowList.get(x);
return columnCount;
}
/**
* 高亮框框移动到"合法"的 第x列,第y行 时, 直接getAdapterPosition返回对应的adapter位置
* <p>
* 高亮框框移动到"非法"的 第x列,第y行 时,
* 1. x方向,移动到最后一列再往右移动,就把高亮框框移动到下一行的第一列
* 2. y方向,上下移动时,上一行或者下一行的当前位置没有item时,移动到上一行或者下一行的最后一个位置
*
* @param x 第x列
* @param y 第y行
* @param highListPosition 当前高亮位置
* @return 第x列,第y行 对应的adapter位置, 如果不存在
*/
public KeyEventHelper.PositionBean moveToNext(int x, int y, int highListPosition) {
if (mCoordinationList.size() <= y) {
return new KeyEventHelper.PositionBean(x, y, ERROR_POSITION);
}
int adapterPosition = getAdapterPosition(x, y);
ArrayList<Integer> rowList = mCoordinationList.get(y);
// 注意,这里是为了应对第一次进入列表情况,可能不能适应所有情况
if (highListPosition == -1 && y == 0) {
return new KeyEventHelper.PositionBean(0, 0, 1);
}
if (adapterPosition == ERROR_POSITION && rowList != null && highListPosition >= 0 && mPositionMap.containsKey(highListPosition)) {
KeyEventHelper.PositionBean lastPosition = mPositionMap.get(highListPosition);
// (x方向上向右移动 && 移动后的x超过的当前行的长度)
if (lastPosition.getX() != x && rowList.size() <= x) {
if (lastPosition.getX() < x) {
/** 1.1 x方向,移动到最后一列再往右移动,就把高亮框框移动到下一行的第一列 */
x = 0;
y += 1;
} else {
/** 1.2 x方向,移动到第一列再往左移动,就把高亮框框移动到上一行的最后一列 */
// 这里目前是走不到的,notouchsupport目前x小于0会跳到导航栏
x = rowList.size() - 1;
y -= 1;
}
// (y方向上或向下移动 && 移动后的x超过的当前行的长度)
} else if (lastPosition.getY() != y && rowList.size() <= x) {
/** 2. y方向,上下移动时,上一行或者下一行的当前位置没有item时,移动到上一行或者下一行的最后一个位置 */
x = rowList.size() - 1;
}
return new KeyEventHelper.PositionBean(x, y, getAdapterPosition(x, y));
}
return new KeyEventHelper.PositionBean(x, y, adapterPosition);
}
public int getTotalCount() {
if (mPositionMap != null) {
return mPositionMap.size();
} else {
return 0;
}
}
public class PositionBean {
// 将会移动到的x轴位置
private int x;
// 将会移动到的y轴位置
private int y;
// xy对应实体在Adapter的位置
private int adapterPosition;
public PositionBean(int x, int y, int position) {
this.x = x;
this.y = y;
this.adapterPosition = position;
}
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 int getAdapterPosition() {
return adapterPosition;
}
public void setAdapterPosition(int adapterPosition) {
this.adapterPosition = adapterPosition;
}
}
}
package com.cneeds.rvhelpers.helpers;
import com.cneeds.rvhelpers.entity.ContentBean;
import com.cneeds.rvhelpers.entity.HeaderBean;
import com.cneeds.rvhelpers.entity.ContentBean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
public class SortDataHelper {
public static List sortData(List<? extends ContentBean> originDataList) {
if (originDataList == null) {
return new ArrayList();
}
LinkedHashMap<String, ArrayList<ContentBean>> hashMap = new LinkedHashMap<>();
for (int i = 0; i < originDataList.size(); i++) {
ContentBean contentBean = originDataList.get(i);
ArrayList<ContentBean> ContentBeanList = hashMap.get(contentBean.getTitle());
if (ContentBeanList == null) {
ContentBeanList = new ArrayList<ContentBean>();
hashMap.put(contentBean.getTitle(), ContentBeanList);
}
ContentBeanList.add(contentBean);
}
ArrayList<Object> returnDataList = new ArrayList<>();
Set<String> keySet = hashMap.keySet();
for (String title : keySet) {
ArrayList<ContentBean> ContentBeanList = hashMap.get(title);
returnDataList.add(new HeaderBean(title));
returnDataList.addAll(ContentBeanList);
}
return returnDataList;
}
}
package com.cneeds.rvhelpers.viewholder;
import android.content.Context;
import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
public abstract class BaseViewHolder<T> extends RecyclerView.ViewHolder {
public BaseViewHolder(Context context, ViewGroup root, int layoutRes) {
super(LayoutInflater.from(context).inflate(layoutRes, root, false));
}
public Context getContext() {
return itemView.getContext();
}
public abstract void bindData(T t, int position, GridRecyclerAdapter adapter);
protected View getView(@IdRes int ir) {
return itemView.findViewById(ir);
}
}
\ No newline at end of file
package com.cneeds.rvhelpers.viewholder;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.cneeds.rvhelpers.R;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
import com.cneeds.rvhelpers.entity.ContentBean;
public class ContentHolder extends BaseViewHolder<ContentBean> {
ImageView mImage;
ImageView mIvHighlightBg;
ImageView mIvSelect;
private Context mContext;
public ContentHolder(Context context, ViewGroup root) {
super(context, root, R.layout.item_grid_content);
mContext = context;
mImage = (ImageView) itemView.findViewById(R.id.image_icon);
mIvHighlightBg = (ImageView) itemView.findViewById(R.id.iv_highlight_bg);
mIvSelect = (ImageView) itemView.findViewById(R.id.iv_select);
}
@Override
public void bindData(final ContentBean s, int position, final GridRecyclerAdapter adapter) {
/**设置背景*/
// Drawable drawable = mContext.getResources().getDrawable(R.drawable.ic_launcher);
// Picasso.with(mImage.getContext()).load(s.getUrl()).error(drawable).into(mImage);
// mImage.setImageURI(Uri.fromFile(new File(s.getUrl())));
/**keyEvent 按键事件的光标框框*/
if (adapter.getCurrentHighLightPosition() == position) {
adapter.setHighListItemView(itemView);
Drawable highlightDrawable = mContext.getResources().getDrawable(R.drawable.rect_solid_border_ff4242);
mIvHighlightBg.setImageDrawable(highlightDrawable);
} else {
Drawable normalDrawable = mContext.getResources().getDrawable(R.drawable.rect_border_bg_242629);
mIvHighlightBg.setImageDrawable(normalDrawable);
}
/**编辑模式切换和选择删除*/
boolean selected = adapter.isSelected(s);
final int finalPosition = position;
if (adapter.getEditMode()) {
mIvSelect.setVisibility(View.VISIBLE);
if (selected) {
Drawable checkedDrawable = mContext.getResources().getDrawable(R.drawable.img_record_lock_success);
mIvSelect.setImageDrawable(checkedDrawable);
} else {
Drawable uncheckedDrawable = mContext.getResources().getDrawable(R.drawable.unchecked_bg);
mIvSelect.setImageDrawable(uncheckedDrawable);
}
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.toggleSelection(v, finalPosition, s);
}
});
} else {
mIvSelect.setVisibility(View.GONE);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.clickItem(v, finalPosition);
}
});
}
}
}
package com.cneeds.rvhelpers.viewholder;
import android.content.Context;
import android.view.ViewGroup;
import android.widget.TextView;
import com.cneeds.rvhelpers.R;
import com.cneeds.rvhelpers.adapter.GridRecyclerAdapter;
import com.cneeds.rvhelpers.entity.HeaderBean;
public class TitleHolder extends BaseViewHolder<HeaderBean> {
private final TextView mTitleName;
public TitleHolder(Context context, ViewGroup root) {
super(context, root, R.layout.item_grid_title);
mTitleName = (TextView) getView(R.id.text_adapter_title_name);
}
@Override
public void bindData(HeaderBean s, int position, GridRecyclerAdapter adapter) {
mTitleName.setText(s.getTitle());
}
}
<vector android:height="24dp" android:tint="#770900"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
<vector android:height="24dp" android:tint="#774F60"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
<?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="1dp" android:color="#242629" />
</shape>
<?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="#ff4242" />
<solid android:color="#00000000" />
<!-- android:radius 圆角的半径 -->
<!-- <corners-->
<!-- android:radius="4px"-->
<!-- />-->
</shape>
\ No newline at end of file
<?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="#ff4242" />
<solid android:color="#00000000" />
<!-- android:radius 圆角的半径 -->
<!-- <corners-->
<!-- android:radius="4px"-->
<!-- />-->
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke android:width="1dp" android:color="#ff4242" />
<solid android:color="#6f7275" />
<size
android:width="38dp"
android:height="38dp" />
</shape>
\ No newline at end of file
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/bg_0c0d11"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:paddingRight="10dp"
android:paddingLeft="10dp">
<ImageView
android:id="@+id/image_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="1dp"
android:background="@drawable/demo_picture"/>
<ImageView
android:id="@+id/iv_highlight_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/rect_border_bg_242629"
/>
<ImageView
android:id="@+id/iv_select"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_margin="7dp"
android:src="@drawable/unchecked_bg"/>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg_0c0d11">
<TextView
android:id="@+id/text_adapter_title_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:layout_marginLeft="10dp"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:textSize="22sp"
android:gravity="top"
android:background="@android:color/transparent"
tools:text="2016年12月28日" />
</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:paddingLeft="24dp"
android:background="@android:color/white"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text_gray">#000000</color>
<color name="activity_color">#eeeeee</color>
<color name="bg_0c0d11">#0c0d11</color>
</resources>
\ No newline at end of file
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="timeline_item_offset_left">68dp</dimen>
<dimen name="timeline_item_node_radius">16dp</dimen>
<dimen name="flag_left">60dp</dimen>
<dimen name="header_divider_height">2dp</dimen>
<dimen name="header_height">24dp</dimen>
<dimen name="header_textsize">22sp</dimen>
</resources>
<resources>
</resources>
\ No newline at end of file
<resources>
</resources>
\ No newline at end of file
include ':notouchsupport-master-363f32dfdde8c261ff34621299138f697bab2bec'
include ':rvHelpers'
include ':app'
rootProject.name = "RecyclerViewDemo2"
\ No newline at end of file
RecyclerViewDemo2еmodule rvHelpersǸDVRĿõĿ
\ No newline at end of file
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