androidx版本首次提交

This commit is contained in:
18401019693
2022-07-18 15:31:45 +08:00
commit 1791a114e3
2932 changed files with 218954 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
package com.sahooz.library;
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.*;
/**
* Instrumentation 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() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.sahooz.library.test", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sahooz.library">
</manifest>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
package com.sahooz.library;
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
//test
public class Adapter extends RecyclerView.Adapter<VH> {
private ArrayList<Country> selectedCountries = new ArrayList<>();
private final LayoutInflater inflater;
private OnPick onPick = null;
private final Context context;
public Adapter(Context ctx) {
inflater = LayoutInflater.from(ctx);
context = ctx;
}
public void setSelectedCountries(ArrayList<Country> selectedCountries) {
this.selectedCountries = selectedCountries;
notifyDataSetChanged();
}
public void setOnPick(OnPick onPick) {
this.onPick = onPick;
}
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
return new VH(inflater.inflate(R.layout.item_country, parent, false));
}
private int itemHeight = -1;
public void setItemHeight(float dp) {
itemHeight = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, dp, context.getResources().getDisplayMetrics());
}
@Override
public void onBindViewHolder(VH holder, int position) {
final Country country = selectedCountries.get(position);
holder.ivFlag.setImageResource(country.flag);
holder.tvName.setText(country.name);
holder.tvCode.setText("+" + country.code);
if(itemHeight != -1) {
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = itemHeight;
holder.itemView.setLayoutParams(params);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onPick != null) onPick.onPick(country);
}
});
}
@Override
public int getItemCount() {
return selectedCountries.size();
}
}

View File

@@ -0,0 +1,120 @@
package com.sahooz.library;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
/**
* Created by android on 17/10/17.
*/
public class Country implements PyEntity {
private static final String TAG = Country.class.getSimpleName();
public int code;
public String name, locale, pinyin;
public int flag;
private static ArrayList<Country> countries = null;
public Country(int code, String name, String locale, int flag) {
this.code = code;
this.name = name;
this.flag = flag;
this.locale = locale;
}
@Override
public String toString() {
return "Country{" +
"code='" + code + '\'' +
"flag='" + flag + '\'' +
", name='" + name + '\'' +
'}';
}
public static ArrayList<Country> getAll(@NonNull Context ctx, @Nullable ExceptionCallback callback) {
if(countries != null) return countries;
countries = new ArrayList<>();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(ctx.getResources().getAssets().open("code.json")));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null)
sb.append(line);
br.close();
JSONArray ja = new JSONArray(sb.toString());
String key = getKey(ctx);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
int flag = 0;
String locale = jo.getString("locale");
if(!TextUtils.isEmpty(locale)) {
flag = ctx.getResources().getIdentifier("flag_" + locale.toLowerCase(), "drawable", ctx.getPackageName());
}
countries.add(new Country(jo.getInt("code"), jo.getString(key), locale, flag));
}
Log.i(TAG, countries.toString());
} catch (IOException e) {
if(callback != null) callback.onIOException(e);
e.printStackTrace();
} catch (JSONException e) {
if(callback != null) callback.onJSONException(e);
e.printStackTrace();
}
return countries;
}
public static Country fromJson(String json){
if(TextUtils.isEmpty(json)) return null;
try {
JSONObject jo = new JSONObject(json);
return new Country(jo.optInt("code") ,jo.optString("name"), jo.optString("locale"), jo.optInt("flag"));
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public String toJson(){
return "{\"name\":\"" + name + "\", \"code\":" + code + ", \"flag\":" + flag + ",\"locale\":\"" + locale + "\"}";
}
public static void destroy(){ countries = null; }
private static String getKey(Context ctx) {
String country = ctx.getResources().getConfiguration().locale.getCountry();
return "CN".equalsIgnoreCase(country)? "zh"
: "TW".equalsIgnoreCase(country)? "tw"
: "HK".equalsIgnoreCase(country)? "tw"
: "en";
}
private static boolean inChina(Context ctx) {
return "CN".equalsIgnoreCase(ctx.getResources().getConfiguration().locale.getCountry());
}
@Override
public int hashCode() {
return code;
}
@NonNull @Override
public String getPinyin() {
if(pinyin == null) {
pinyin = PinyinUtil.getPingYin(name);
}
return pinyin;
}
}

View File

@@ -0,0 +1,79 @@
package com.sahooz.library;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import java.util.ArrayList;
/**
* Created by android on 17/10/17.
*/
public class CountryPicker extends DialogFragment {
private ArrayList<Country> allCountries = new ArrayList<>();
private ArrayList<Country> selectedCountries = new ArrayList<>();
private OnPick onPick;
public CountryPicker() { }
public static CountryPicker newInstance(Bundle args, OnPick onPick) {
CountryPicker picker = new CountryPicker();
picker.setArguments(args);
picker.onPick = onPick;
return picker;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.dialog_country_picker, container, false);
EditText etSearch = (EditText) root.findViewById(R.id.et_search);
final RecyclerView rvCountry = (RecyclerView) root.findViewById(R.id.rv_country);
allCountries.clear();
allCountries.addAll(Country.getAll(getContext(), null));
selectedCountries.clear();
selectedCountries.addAll(allCountries);
final Adapter adapter = new Adapter(getContext());
adapter.setOnPick(new OnPick() {
@Override
public void onPick(Country country) {
dismiss();
if(onPick != null) onPick.onPick(country);
}
});
// adapter.setOnPick(country -> {
// dismiss();
// if(onPick != null) onPick.onPick(country);
// });
adapter.setSelectedCountries(selectedCountries);
rvCountry.setAdapter(adapter);
rvCountry.setLayoutManager(new LinearLayoutManager(getContext()));
etSearch.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
@Override public void afterTextChanged(Editable s) {
String string = s.toString();
selectedCountries.clear();
for (Country country : allCountries) {
String codes = country.code+"";
if(country.name.toLowerCase().contains(string.toLowerCase())||codes.contains(string.toLowerCase()))
selectedCountries.add(country);
}
adapter.notifyDataSetChanged();
}
});
return root;
}
}

View File

@@ -0,0 +1,14 @@
package com.sahooz.library;
import org.json.JSONException;
import java.io.IOException;
/**
* Created by android on 17/10/17.
*/
public abstract class ExceptionCallback {
public abstract void onIOException(IOException e);
public abstract void onJSONException(JSONException e);
}

View File

@@ -0,0 +1,13 @@
package com.sahooz.library;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
public class LetterHolder extends RecyclerView.ViewHolder {
public final TextView textView;
public LetterHolder(View itemView) {
super(itemView);
textView = (TextView) itemView;
}
}

View File

@@ -0,0 +1,9 @@
package com.sahooz.library;
/**
* Created by android on 17/10/17.
*/
public interface OnPick {
void onPick(Country country);
}

View File

@@ -0,0 +1,124 @@
package com.sahooz.library;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class PickActivity extends AppCompatActivity {
private ArrayList<Country> selectedCountries = new ArrayList<>();
private ArrayList<Country> allCountries = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pick);
RecyclerView rvPick = (RecyclerView) findViewById(R.id.rv_pick);
SideBar side = (SideBar) findViewById(R.id.side);
EditText etSearch = (EditText) findViewById(R.id.et_search);
final TextView tvLetter = (TextView) findViewById(R.id.tv_letter);
allCountries.clear();
allCountries.addAll(Country.getAll(this, null));
selectedCountries.clear();
selectedCountries.addAll(allCountries);
final CAdapter adapter = new CAdapter(selectedCountries);
rvPick.setAdapter(adapter);
final LinearLayoutManager manager = new LinearLayoutManager(this);
rvPick.setLayoutManager(manager);
rvPick.setAdapter(adapter);
rvPick.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
etSearch.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
@Override public void afterTextChanged(Editable s) {
String string = s.toString();
selectedCountries.clear();
for (Country country : allCountries) {
if(country.name.toLowerCase().contains(string.toLowerCase()))
selectedCountries.add(country);
}
adapter.update(selectedCountries);
}
});
side.addIndex("#", side.indexes.size());
side.setOnLetterChangeListener(new SideBar.OnLetterChangeListener() {
@Override
public void onLetterChange(String letter) {
tvLetter.setVisibility(View.VISIBLE);
tvLetter.setText(letter);
int position = adapter.getLetterPosition(letter);
if (position != -1) {
manager.scrollToPositionWithOffset(position, 0);
}
}
@Override
public void onReset() {
tvLetter.setVisibility(View.GONE);
}
});
}
class CAdapter extends PyAdapter<RecyclerView.ViewHolder> {
public CAdapter(List<? extends PyEntity> entities) {
super(entities);
}
@Override
public RecyclerView.ViewHolder onCreateLetterHolder(ViewGroup parent, int viewType) {
return new LetterHolder(getLayoutInflater().inflate(R.layout.item_letter, parent, false));
}
@Override
public RecyclerView.ViewHolder onCreateHolder(ViewGroup parent, int viewType) {
return new VH(getLayoutInflater().inflate(R.layout.item_country_large_padding, parent, false));
}
@Override
public void onBindHolder(RecyclerView.ViewHolder holder, PyEntity entity, int position) {
VH vh = (VH)holder;
final Country country = (Country)entity;
vh.ivFlag.setImageResource(country.flag);
vh.tvName.setText(country.name);
vh.tvCode.setText("+" + country.code);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent data = new Intent();
data.putExtra("country", country.toJson());
setResult(Activity.RESULT_OK , data);
finish();
}
});
// holder.itemView.setOnClickListener(v -> {
// Intent data = new Intent();
// data.putExtra("country", country.toJson());
// setResult(Activity.RESULT_OK , data);
// finish();
// });
}
@Override
public void onBindLetterHolder(RecyclerView.ViewHolder holder, LetterEntity entity, int position) {
((LetterHolder)holder).textView.setText(entity.letter.toUpperCase());
}
}
}

View File

@@ -0,0 +1,14 @@
package com.sahooz.library;
import com.github.promeg.pinyinhelper.Pinyin;
public class PinyinUtil {
public static String getPingYin(String inputString) {
try {
return Pinyin.toPinyin(inputString, "");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}

View File

@@ -0,0 +1,199 @@
package com.sahooz.library;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.WeakHashMap;
/**
* Created by android on 3/15/2018.
*/
public abstract class PyAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements View.OnClickListener {
private static final String TAG = PyAdapter.class.getSimpleName();
public static final int TYPE_LETTER = 0;
public static final int TYPE_OTHER = 1;
private WeakHashMap<View, VH> holders = new WeakHashMap<>();
public final ArrayList<PyEntity> entityList = new ArrayList<>();
public final HashSet<LetterEntity> letterSet = new HashSet<>();
private OnItemClickListener listener=new OnItemClickListener() {
@Override
public void onItemClick(PyEntity entity, int position) {
}
};
// private OnItemClickListener listener = (entity, position) -> {
//
// };
public PyAdapter(List<? extends PyEntity> entities){
if(entities == null) throw new NullPointerException("entities == null!");
update(entities);
}
public void update(List<? extends PyEntity> entities){
if(entities == null) throw new NullPointerException("entities == null!");
entityList.clear();
entityList.addAll(entities);
letterSet.clear();
for (PyEntity entity : entities) {
String pinyin = entity.getPinyin();
if(!TextUtils.isEmpty(pinyin)) {
char letter = pinyin.charAt(0);
if(!isLetter(letter))
letter = 35;
letterSet.add(new LetterEntity(letter + ""));
}
}
entityList.addAll(letterSet);
Collections.sort(entityList, new Comparator<PyEntity>() {
@Override
public int compare(PyEntity o1, PyEntity o2) {
String pinyin = o1.getPinyin().toLowerCase();
String anotherPinyin = o2.getPinyin().toLowerCase();
char letter = pinyin.charAt(0);
char otherLetter = anotherPinyin.charAt(0);
if(isLetter(letter) && isLetter(otherLetter))
return pinyin.compareTo(anotherPinyin);
else if(isLetter(letter) && !isLetter(otherLetter)) {
return -1;
} else if(!isLetter(letter) && isLetter(otherLetter)){
return 1;
} else {
if(letter == 35 && o1 instanceof LetterEntity) return -1;
else if(otherLetter == 35 && o2 instanceof LetterEntity) return 1;
else return pinyin.compareTo(anotherPinyin);
}
}
});
// Collections.sort(entityList, (o1, o2) -> {
// String pinyin = o1.getPinyin().toLowerCase();
// String anotherPinyin = o2.getPinyin().toLowerCase();
// char letter = pinyin.charAt(0);
// char otherLetter = anotherPinyin.charAt(0);
// if(isLetter(letter) && isLetter(otherLetter))
// return pinyin.compareTo(anotherPinyin);
// else if(isLetter(letter) && !isLetter(otherLetter)) {
// return -1;
// } else if(!isLetter(letter) && isLetter(otherLetter)){
// return 1;
// } else {
// if(letter == 35 && o1 instanceof LetterEntity) return -1;
// else if(otherLetter == 35 && o2 instanceof LetterEntity) return 1;
// else return pinyin.compareTo(anotherPinyin);
// }
// });
notifyDataSetChanged();
}
private boolean isLetter(char letter) {
return 'a' <= letter && 'z' >= letter || 'A' <= letter && 'Z' >= letter;
}
@Override
public final void onBindViewHolder(VH holder, int position) {
PyEntity entity = entityList.get(position);
holders.put(holder.itemView, holder);
holder.itemView.setOnClickListener(this);
if(entity instanceof LetterEntity) {
onBindLetterHolder(holder, (LetterEntity)entity, position);
} else {
onBindHolder(holder, entity, position);
}
}
public int getEntityPosition(PyEntity entity) { return entityList.indexOf(entity); }
@Override
public final VH onCreateViewHolder(ViewGroup parent, int viewType) {
return viewType == TYPE_LETTER? onCreateLetterHolder(parent, viewType)
: onCreateHolder(parent, viewType);
}
public abstract VH onCreateLetterHolder(ViewGroup parent, int viewType);
public abstract VH onCreateHolder(ViewGroup parent, int viewType);
public int getLetterPosition(String letter){
LetterEntity entity = new LetterEntity(letter);
return entityList.indexOf(entity);
}
@Override
public int getItemViewType(int position) {
PyEntity entity = entityList.get(position);
return entity instanceof LetterEntity? TYPE_LETTER : getViewType(entity, position);
}
public int getViewType(PyEntity entity, int position) {
return TYPE_OTHER;
}
@Override
public final int getItemCount() { return entityList.size(); }
public void onBindLetterHolder(VH holder, LetterEntity entity, int position) {
}
public void onBindHolder(VH holder, PyEntity entity, int position) {
}
public boolean isLetter(int position) {
if(position < 0 || position >= entityList.size()) return false;
else return entityList.get(position) instanceof LetterEntity;
}
public interface OnItemClickListener {
void onItemClick(PyEntity entity, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
@Override
public final void onClick(View v) {
VH holder = holders.get(v);
if(holder == null) {
Log.e(TAG, "Holder onClick event, but why holder == null?");
return;
}
int position = holder.getAdapterPosition();
PyEntity pyEntity = entityList.get(position);
listener.onItemClick(pyEntity, position);
}
public static final class LetterEntity implements PyEntity {
public final String letter;
public LetterEntity(String letter) { this.letter = letter; }
@Override @NonNull
public String getPinyin() { return letter.toLowerCase(); }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LetterEntity that = (LetterEntity) o;
return letter.toLowerCase().equals(that.letter.toLowerCase());
}
@Override
public int hashCode() { return letter.toLowerCase().hashCode(); }
}
}

View File

@@ -0,0 +1,11 @@
package com.sahooz.library;
import androidx.annotation.NonNull;
/**
* Created by android on 3/15/2018.
*/
public interface PyEntity {
@NonNull String getPinyin();
}

View File

@@ -0,0 +1,171 @@
package com.sahooz.library;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by android on 3/14/2018.
*/
public class SideBar extends View {
public final ArrayList<String> indexes = new ArrayList<>();
private OnLetterChangeListener onLetterChangeListener;
private Paint paint;
private float textHeight;
private int cellWidth;
private int cellHeight;
private int currentIndex = -1;
private int letterColor;
private int selectColor;
private int letterSize;
public SideBar(Context context) { this(context, null); }
public SideBar(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SideBar, defStyleAttr, 0);
letterColor = ta.getColor(R.styleable.SideBar_letterColor, Color.BLACK);
selectColor = ta.getColor(R.styleable.SideBar_selectColor, Color.CYAN);
letterSize = ta.getDimensionPixelSize(R.styleable.SideBar_letterSize, 24);
ta.recycle();
paint = new Paint();
//消除锯齿
paint.setAntiAlias(true);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
textHeight = (float) Math.ceil(fontMetrics.descent - fontMetrics.ascent); //1.1---2 2.1--3
String[] letters = {"A", "B", "C", "D",
"E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
indexes.addAll(Arrays.asList(letters));
}
public void addIndex(String indexStr, int position) {
indexes.add(position, indexStr);
invalidate();
}
public void removeIndex(String indexStr) {
indexes.remove(indexStr);
invalidate();
}
public void setLetterSize(int letterSize) {
if(this.letterSize == letterSize) return;
this.letterSize = letterSize;
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
cellWidth = getMeasuredWidth();
cellHeight = getMeasuredHeight() / indexes.size();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setTextSize(letterSize);
for (int i = 0; i < indexes.size(); i++) {
String letter = indexes.get(i);
float textWidth = paint.measureText(letter);
float x = (cellWidth - textWidth) * 0.5f;
float y = (cellHeight + textHeight) * 0.5f + cellHeight * i;
if (i == currentIndex) {
paint.setColor(selectColor);
} else {
paint.setColor(letterColor);
}
canvas.drawText(letter, x, y, paint);
}
}
public OnLetterChangeListener getOnLetterChangeListener() {
return onLetterChangeListener;
}
public void setOnLetterChangeListener(OnLetterChangeListener onLetterChangeListener) {
this.onLetterChangeListener = onLetterChangeListener;
}
public String getLetter(int position) {
if(position < 0 || position >= indexes.size()) return "";
return indexes.get(position);
}
public interface OnLetterChangeListener {
void onLetterChange(String letter);
//手指抬起
void onReset();
}
/**
* 处理 按下 移动 手指抬起
*/
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int downY = (int) event.getY();
//获取当前索引
currentIndex = downY / cellHeight;
if (currentIndex < 0 || currentIndex > indexes.size() - 1) {
} else {
if (onLetterChangeListener != null) {
onLetterChangeListener.onLetterChange(indexes.get(currentIndex));
}
}
//重新绘制
invalidate();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) event.getY();
//获取当前索引
currentIndex = moveY / cellHeight;
if (currentIndex < 0 || currentIndex > indexes.size() - 1) {
} else {
if (onLetterChangeListener != null) {
onLetterChangeListener.onLetterChange(indexes.get(currentIndex));
}
}
//重新绘制
invalidate();
break;
case MotionEvent.ACTION_UP:
currentIndex = -1;
//手动刷新
invalidate();
//表示手指抬起了
if (onLetterChangeListener != null) {
onLetterChangeListener.onReset();
}
break;
}
// 为了 能够接受 move+up事件
return true;
}
}

View File

@@ -0,0 +1,20 @@
package com.sahooz.library;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
class VH extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvCode;
ImageView ivFlag;
VH(View itemView) {
super(itemView);
ivFlag = (ImageView) itemView.findViewById(R.id.iv_flag);
tvName = (TextView) itemView.findViewById(R.id.tv_name);
tvCode = (TextView) itemView.findViewById(R.id.tv_code);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Some files were not shown because too many files have changed in this diff Show More