Browse Source

feat: 💺 icon选择器

master
niushuai233 1 year ago
parent
commit
076a0c3dd6
  1. 3
      app/src/main/java/cc/niushuai/dididone/ui/setting/icon/IconFragment.java
  2. 52
      app/src/main/java/cc/niushuai/dididone/ui/setting/icon/recycle/IconRecycleAdapter.java
  3. 178
      app/src/main/java/cc/niushuai/dididone/ui/setting/project/NewProjectActivity.java
  4. 15
      app/src/main/res/layout/fragment_icon.xml
  5. 36
      app/src/main/res/layout/fragment_icon_dialog.xml
  6. 6
      app/src/main/res/layout/icon_grid_item.xml
  7. 1
      app/src/main/res/values/colors.xml

3
app/src/main/java/cc/niushuai/dididone/ui/setting/icon/IconFragment.java

@ -18,6 +18,7 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.fontawesome_typeface_library.FontAwesome; import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import java.util.ArrayList; import java.util.ArrayList;
@ -108,7 +109,7 @@ public class IconFragment extends Fragment implements InitAndSetListener {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
binding.iconsRecyclerView.setLayoutManager(layoutManager); binding.iconsRecyclerView.setLayoutManager(layoutManager);
iconRecycleAdapter = new IconRecycleAdapter(getActivity(), FontAwesome.Icon.class); iconRecycleAdapter = new IconRecycleAdapter(getActivity(), CommunityMaterial.Icon.class);
binding.iconsRecyclerView.setAdapter(iconRecycleAdapter); binding.iconsRecyclerView.setAdapter(iconRecycleAdapter);
} }

52
app/src/main/java/cc/niushuai/dididone/ui/setting/icon/recycle/IconRecycleAdapter.java

@ -1,6 +1,8 @@
package cc.niushuai.dididone.ui.setting.icon.recycle; package cc.niushuai.dididone.ui.setting.icon.recycle;
import android.content.Context; import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
@ -12,31 +14,36 @@ import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.typeface.IIcon; import com.mikepenz.iconics.typeface.IIcon;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cc.niushuai.dididone.MainActivity;
import cc.niushuai.dididone.R; import cc.niushuai.dididone.R;
import cc.niushuai.dididone.biz.entity.SavedIcon; import cc.niushuai.dididone.biz.entity.SavedIcon;
import cc.niushuai.dididone.databinding.IconGridItemBinding;
import cc.niushuai.dididone.util.XLog;
public class IconRecycleAdapter extends RecyclerView.Adapter<IconRecycleAdapter.IconRecycleViewHolder> { public class IconRecycleAdapter extends RecyclerView.Adapter<IconRecycleAdapter.IconRecycleViewHolder> {
public static final Map<String, List<SavedIcon>> ICON_MAP = new HashMap<>(); public static final Map<String, List<SavedIcon>> ICON_MAP = new HashMap<>();
private Class<? extends IIcon> iconClass; private Class<? extends IIcon> iconClass;
private List<SavedIcon> savedIconList; private List<SavedIcon> savedIconList;
private Activity activity;
private Context context; private String selectedIcon;
public IconRecycleAdapter(Context context, Class<? extends IIcon> iconClass) { public IconRecycleAdapter(Activity activity, Class<? extends IIcon> iconClass) {
this.context = context; this.activity = activity;
this.iconClass = iconClass; this.iconClass = iconClass;
change(getIconClassName(iconClass), item -> true); change(getIconClassName(iconClass), item -> true);
} }
public String getSelectedIcon() {
return selectedIcon;
}
public void change(String name, Predicate<? super SavedIcon> filter) { public void change(String name, Predicate<? super SavedIcon> filter) {
if (null == name) { if (null == name) {
name = getIconClassName(iconClass); name = getIconClassName(iconClass);
@ -54,10 +61,13 @@ public class IconRecycleAdapter extends RecyclerView.Adapter<IconRecycleAdapter.
@NonNull @NonNull
@Override @Override
public IconRecycleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public IconRecycleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.icon_grid_item, null); // View view = View.inflate(activity, R.layout.icon_grid_item, null);
return new IconRecycleViewHolder(view); // return new IconRecycleViewHolder(view);
return new IconRecycleViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.icon_grid_item, parent, false));
} }
int selectedPosition = -1;
int lastSelectedPosition = -1;
/** /**
* @param holder The ViewHolder which should be updated to represent the contents of the * @param holder The ViewHolder which should be updated to represent the contents of the
* item at the given position in the data set. * item at the given position in the data set.
@ -66,12 +76,27 @@ public class IconRecycleAdapter extends RecyclerView.Adapter<IconRecycleAdapter.
@Override @Override
public void onBindViewHolder(@NonNull IconRecycleViewHolder holder, int position) { public void onBindViewHolder(@NonNull IconRecycleViewHolder holder, int position) {
SavedIcon icon = savedIconList.get(position); SavedIcon icon = savedIconList.get(position);
holder.iconView.setImageDrawable(new IconicsDrawable(context) holder.iconView.setImageDrawable(new IconicsDrawable(activity)
.icon(icon.getIcon()) .icon(icon.getIcon())
.color(Integer.parseInt(icon.getColor())) .color(Integer.parseInt(icon.getColor()))
.sizeDp(icon.getSize())); .sizeDp(icon.getSize()));
holder.txtView.setText(icon.getIcon()); holder.txtView.setText(icon.getIcon());
holder.binding.getRoot().setOnClickListener(v -> {
lastSelectedPosition = selectedPosition;
selectedPosition = holder.getBindingAdapterPosition();
notifyItemChanged(lastSelectedPosition);
notifyItemChanged(selectedPosition);
});
if (selectedPosition == holder.getBindingAdapterPosition()) {
holder.binding.iconsGridLayout.setBackgroundColor(activity.getColor(R.color.theme_color_primary));
} else {
holder.binding.iconsGridLayout.setBackgroundColor(Color.WHITE);
}
selectedIcon = icon.getIcon();
XLog.d("onItemClick position: {}, icon: {}, selectedIcon: {}", position, icon.getIcon(), selectedIcon);
} }
/** /**
@ -87,17 +112,22 @@ public class IconRecycleAdapter extends RecyclerView.Adapter<IconRecycleAdapter.
return iconClassName.substring(iconClassName.lastIndexOf(".") + 1, iconClassName.indexOf("$")); return iconClassName.substring(iconClassName.lastIndexOf(".") + 1, iconClassName.indexOf("$"));
} }
public static class IconRecycleViewHolder extends RecyclerView.ViewHolder {
public class IconRecycleViewHolder extends RecyclerView.ViewHolder {
private IconGridItemBinding binding;
protected ImageView iconView; protected ImageView iconView;
protected TextView txtView; protected TextView txtView;
public IconRecycleViewHolder(@NonNull View itemView) { public IconRecycleViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
binding = IconGridItemBinding.bind(itemView);
iconView = itemView.findViewById(R.id.icons_grid_item); iconView = itemView.findViewById(R.id.icons_grid_item);
txtView = itemView.findViewById(R.id.icons_grid_txt); txtView = itemView.findViewById(R.id.icons_grid_txt);
} }
} }
} }

178
app/src/main/java/cc/niushuai/dididone/ui/setting/project/NewProjectActivity.java

@ -3,9 +3,22 @@ package cc.niushuai.dididone.ui.setting.project;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity; import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
import com.skydoves.colorpickerview.ColorEnvelope; import com.skydoves.colorpickerview.ColorEnvelope;
import com.skydoves.colorpickerview.ColorPickerDialog; import com.skydoves.colorpickerview.ColorPickerDialog;
@ -13,10 +26,17 @@ import com.skydoves.colorpickerview.ColorPickerView;
import com.skydoves.colorpickerview.listeners.ColorEnvelopeListener; import com.skydoves.colorpickerview.listeners.ColorEnvelopeListener;
import com.skydoves.colorpickerview.listeners.ColorListener; import com.skydoves.colorpickerview.listeners.ColorListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.function.Predicate;
import cc.niushuai.dididone.R; import cc.niushuai.dididone.R;
import cc.niushuai.dididone.biz.BizGlobal; import cc.niushuai.dididone.biz.BizGlobal;
import cc.niushuai.dididone.biz.entity.SavedIcon;
import cc.niushuai.dididone.databinding.ActivityNewProjectBinding; import cc.niushuai.dididone.databinding.ActivityNewProjectBinding;
import cc.niushuai.dididone.ui.base.BaseActivity; import cc.niushuai.dididone.ui.base.BaseActivity;
import cc.niushuai.dididone.ui.setting.icon.recycle.IconRecycleAdapter;
import cc.niushuai.dididone.util.Toasts; import cc.niushuai.dididone.util.Toasts;
import cc.niushuai.dididone.util.XLog; import cc.niushuai.dididone.util.XLog;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
@ -26,6 +46,12 @@ public class NewProjectActivity extends BaseActivity {
private ActivityNewProjectBinding binding; private ActivityNewProjectBinding binding;
private int selectedColor = -324225874; private int selectedColor = -324225874;
private String selectedIcon = CommunityMaterial.Icon.cmd_access_point.name();
/**
* icon 展示 recycleViewAdapter
*/
private IconRecycleAdapter iconRecycleAdapter;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -43,14 +69,110 @@ public class NewProjectActivity extends BaseActivity {
setTitle("添加新打卡项"); setTitle("添加新打卡项");
} }
private void initIconDialogView(View iconDialogView) {
initIconDialogRecyclerView(iconDialogView);
initIconDialogSpinner(iconDialogView);
addIconDialogSearchTxtListener(iconDialogView);
}
private void addIconDialogSearchTxtListener(View iconDialogView) {
TextView iconDialogSearchTxtView = iconDialogView.findViewById(R.id.icons_dialog_search);
iconDialogSearchTxtView.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) {
iconRecycleAdapter.change(null, item -> item.getIcon().contains(s.toString()));
}
});
}
private void initIconDialogRecyclerView(View iconDialogView) {
RecyclerView iconDialogRecyclerView = iconDialogView.findViewById(R.id.icons_dialog_recyclerView);
iconDialogRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
DefaultItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(1000);
itemAnimator.setRemoveDuration(1000);
iconDialogRecyclerView.setItemAnimator(itemAnimator);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
iconDialogRecyclerView.setLayoutManager(layoutManager);
iconRecycleAdapter = new IconRecycleAdapter(this, CommunityMaterial.Icon.class);
iconDialogRecyclerView.setAdapter(iconRecycleAdapter);
}
private void initIconDialogSpinner(View iconDialogView) {
Set<String> keySet = IconRecycleAdapter.ICON_MAP.keySet();
ArrayList<String> keys = new ArrayList<>(keySet);
Collections.sort(keys);
Spinner iconDialogSpinner = iconDialogView.findViewById(R.id.icons_dialog_select);
iconDialogSpinner.setAdapter(new ArrayAdapter<String>(this, com.necer.R.layout.support_simple_spinner_dropdown_item, keys));
iconDialogSpinner.setSelection(0);
iconDialogSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String key = keys.get(position);
String str = ((TextView) iconDialogView.findViewById(R.id.icons_dialog_search)).getText().toString();
Predicate<SavedIcon> filter = item -> true;
if (null != str && str.length() > 0) {
filter = item -> item.getIcon().contains(str);
}
iconRecycleAdapter.change(key, filter);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
@Override @Override
protected void setListeners() { protected void setListeners() {
// icon选择器 // icon选择器
binding.npIconFill.setOnClickListener(view -> { iconClickListener();
});
// 颜色选择器 // 颜色选择器
colorPickListener();
// 返回按钮
binding.npButtonBack.setOnClickListener(view -> finish());
// 确定按钮
binding.npButtonConfirm.setOnClickListener(view -> {
// 三种属性
Intent data = new Intent();
// 名称
String projectName = binding.npProjectNameTxt.getText().toString();
if (StrUtil.isEmpty(projectName)) {
Toasts.shortShow(this, "{}未填", getResources().getString(R.string.np_project_name));
}
data.putExtra(BizGlobal.PROJECT_NAME, projectName);
// 图标
data.putExtra(BizGlobal.PROJECT_ICON, selectedIcon);
// 颜色
data.putExtra(BizGlobal.PROJECT_ICON_COLOR, selectedColor);
// 放置结果数据
setResult(BizGlobal.REQUEST_CODE_GENERAL, data);
finish();
});
}
private void colorPickListener() {
binding.npColorPicker.setOnClickListener(view -> { binding.npColorPicker.setOnClickListener(view -> {
ColorPickerDialog.Builder builder = new ColorPickerDialog.Builder(this); ColorPickerDialog.Builder builder = new ColorPickerDialog.Builder(this);
@ -81,7 +203,8 @@ public class NewProjectActivity extends BaseActivity {
XLog.d("选择的颜色:{} {} {}, fromUser: {}", envelope.getColor(), envelope.getArgb(), envelope.getHexCode(), fromUser); XLog.d("选择的颜色:{} {} {}, fromUser: {}", envelope.getColor(), envelope.getArgb(), envelope.getHexCode(), fromUser);
selectedColor = envelope.getColor(); selectedColor = envelope.getColor();
changeIconColor(envelope.getColor()); // 改变图标以及颜色
changeIcon(null, selectedColor);
} }
}) })
.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> { .setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
@ -94,33 +217,40 @@ public class NewProjectActivity extends BaseActivity {
builder.create().show(); builder.create().show();
}); });
}
// 返回按钮 private void iconClickListener() {
binding.npButtonBack.setOnClickListener(view -> finish());
// 确定按钮 binding.npIconFill.setOnClickListener(view -> {
binding.npButtonConfirm.setOnClickListener(view -> {
// 三种属性 View iconDialogView = View.inflate(this, R.layout.fragment_icon_dialog, null);
Intent data = new Intent(); // 初始化 并且添加监听事件
// 名称 initIconDialogView(iconDialogView);
String projectName = binding.npProjectNameTxt.getText().toString();
if (StrUtil.isEmpty(projectName)) { AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("选择一个图标");
Toasts.shortShow(this, "{}未填", getResources().getString(R.string.np_project_name)); AlertDialog alertDialog = builder.setView(iconDialogView)
} .setNegativeButton("返回", (dialog, which) -> dialog.dismiss())
data.putExtra(BizGlobal.PROJECT_NAME, projectName); .setPositiveButton("选择该图标", (dialog, which) -> {
// 图标 selectedIcon = iconRecycleAdapter.getSelectedIcon();
data.putExtra(BizGlobal.PROJECT_ICON, binding.npProjectNameTxt.getText().toString()); changeIcon(selectedIcon, selectedColor);
// 颜色 }).create();
data.putExtra(BizGlobal.PROJECT_ICON_COLOR, binding.npProjectNameTxt.getText().toString());
// 放置结果数据 alertDialog.show();
setResult(BizGlobal.REQUEST_CODE_GENERAL, data);
finish();
}); });
} }
private void changeIconColor(int color) { /**
* 改变图标以及颜色
*
* @param icon 图标
* @param color 颜色
*/
private void changeIcon(String icon, int color) {
if (StrUtil.isEmpty(icon)) {
icon = ReflectUtil.getFieldValue(binding.npIconFill.getDrawable(), "mIcon").toString();
}
binding.npIconFill.setImageDrawable(new IconicsDrawable(this) binding.npIconFill.setImageDrawable(new IconicsDrawable(this)
.icon(ReflectUtil.getFieldValue(binding.npIconFill.getDrawable(), "mIcon").toString()) .icon(icon)
.color(color) .color(color)
.sizeDp(50) .sizeDp(50)
); );

15
app/src/main/res/layout/fragment_icon.xml

@ -12,8 +12,7 @@
<Spinner <Spinner
android:id="@+id/icons_select" android:id="@+id/icons_select"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="35dp" android:layout_height="35dp" />
/>
<EditText <EditText
android:id="@+id/icons_search" android:id="@+id/icons_search"
@ -22,17 +21,17 @@
android:layout_marginLeft="15dp" android:layout_marginLeft="15dp"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:layout_marginRight="15dp" android:layout_marginRight="15dp"
android:scrollHorizontally="true" android:background="@drawable/bg_miui10"
android:lines="1"
android:inputType="text"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:background="@drawable/bg_miui10" /> android:inputType="text"
android:lines="1"
android:scrollHorizontally="true" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/icons_recyclerView" android:id="@+id/icons_recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="20px"
android:clipToPadding="false" android:clipToPadding="false"
android:scrollbars="vertical"/> android:scrollbars="vertical" />
</LinearLayout> </LinearLayout>

36
app/src/main/res/layout/fragment_icon_dialog.xml

@ -0,0 +1,36 @@
<?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:background="#4DD5D1D1"
android:orientation="vertical"
android:padding="10dp">
<Spinner
android:id="@+id/icons_dialog_select"
android:layout_width="match_parent"
android:layout_height="35dp" />
<EditText
android:id="@+id/icons_dialog_search"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_miui10"
android:imeOptions="actionDone"
android:inputType="text"
android:lines="1"
android:scrollHorizontally="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/icons_dialog_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20px"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>

6
app/src/main/res/layout/icon_grid_item.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/icons_grid_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto" android:padding="20dp">
android:padding="10dp">
<ImageView <ImageView
android:id="@+id/icons_grid_item" android:id="@+id/icons_grid_item"

1
app/src/main/res/values/colors.xml

@ -9,6 +9,7 @@
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="red">#FFFF0000</color> <color name="red">#FFFF0000</color>
<color name="theme_color_primary">#F0B82B</color>
<color name="_333333">#333333</color> <color name="_333333">#333333</color>
<color name="_666666">#666666</color> <color name="_666666">#666666</color>
<color name="s_yellow">#F8FF26</color> <color name="s_yellow">#F8FF26</color>

Loading…
Cancel
Save