first commit

This commit is contained in:
GP
2025-08-13 14:51:35 +08:00
commit 905f9f62f2
377 changed files with 64971 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.util.GradientDrawableBuilder;
import com.bytecat.algui.component.Stack;
import android.graphics.Typeface;
import com.bytecat.algui.layoutparams.StackParams;
import android.view.Gravity;
public class BoxButton extends Stack {
public String buttonText;
public Text text;
private ClickCallback clickCallback;
public BoxButton(String buttonText) {
this.buttonText = buttonText;
setBackground(
new GradientDrawableBuilder()
.setColor(hexColor("#00000000"))
.setAllRadius(dip2px(8))
);
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickCallback != null) {
clickCallback.onClick();
}
}
});
text = new Text()
.setText(buttonText)
.setTextSize(10f)
.setTextColor(hexColor("#00000000"))
.setTypeface(Typeface.DEFAULT_BOLD)
.setLayoutParams(
new StackParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setGravity(Gravity.CENTER)
.setMargins(dip2pxInt(15), dip2pxInt(5), dip2pxInt(15), dip2pxInt(5))
);
addView(text);
}
public BoxButton() {
this("button.common.run");
}
public BoxButton setClickCallback(ClickCallback clickCallback) {
this.clickCallback = clickCallback;
return this;
}
}

View File

@@ -0,0 +1,107 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.graphics.Typeface;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import android.widget.RelativeLayout;
public class BoxContent extends Relative {
public static final int BUTTON_ID = View.generateViewId();
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public BoxButton mButton; // 使用 Button
public BoxContent(String title) {
this(title, null);
}
public BoxContent(String title, String description) {
this(title, description, false);
}
public BoxContent(String title, String description, boolean isChecked) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.START_OF, BUTTON_ID)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#FF999999"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
mButton = new BoxButton(""); // 可以根据需要修改按钮文本
mButton.setId(BUTTON_ID).setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(mButton);
}
// 添加设置按钮点击回调的方法
public BoxContent setButtonCallback(ClickCallback clickCallback) {
mButton.setClickCallback(clickCallback);
return this;
}
}

View File

@@ -0,0 +1,127 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
public class BoxContentCard extends ContentCard {
public BoxContent BoxContent;
public Column expandableContentContainer;
public Widget divider;
public ViewHelper<?> expandableContent;
public boolean isExpanded;
// ===== 追加字段 =====
private String chineseTitle;
private String chineseDescription;
private String englishTitle;
private String englishDescription;
private String languageSwitchFilePath;
// ===== 追加 API =====
public BoxContentCard OText(String chineseTitle, String chineseDescription,
String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
return this;
}
public BoxContentCard OText(String chineseTitle, String chineseDescription) {
return OText(chineseTitle, chineseDescription, null, null);
}
public BoxContentCard setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
private void updateTextBasedOnFile() {
boolean fileExists = new java.io.File(languageSwitchFilePath).exists();
if (fileExists) {
BoxContent.titleText.setText(chineseTitle);
if (BoxContent.descriptionText != null) {
BoxContent.descriptionText.setText(chineseDescription);
}
} else {
if (englishTitle != null && englishDescription != null) {
BoxContent.titleText.setText(englishTitle);
if (BoxContent.descriptionText != null) {
BoxContent.descriptionText.setText(englishDescription);
}
}
}
}
public BoxContentCard(String title, String description, boolean isChecked) {
BoxContent = new BoxContent(title, description, isChecked);
BoxContent.setLayoutParams(
new LinearParams()
.setAllMargins(dip2pxInt(15))
);
addView(BoxContent);
expandableContentContainer = new Column()
.setVisibility(View.GONE)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(dip2pxInt(15), 0, dip2pxInt(15), dip2pxInt(15))
);
addView(expandableContentContainer);
divider = new Widget()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(dip2pxInt(1))
)
.setBackgroundColor(hexColor("#40D0D0D0"));
expandableContentContainer.addView(divider);
}
public BoxContentCard(String title, String description) {
this(title, description, false);
}
public BoxContentCard(String title) {
this(title, null, false);
}
public BoxContentCard setClickCallback(ClickCallback clickCallback) {
BoxContent.setButtonCallback(clickCallback);
return this;
}
public BoxContentCard setExpandableContent(ViewHelper<?> expandableContent) {
this.expandableContent = expandableContent;
if (expandableContent != null) {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (build().getLayoutTransition().isRunning()) {
return;
}
isExpanded = !isExpanded;
if (isExpanded) {
expandableContentContainer.setVisibility(View.VISIBLE);
} else {
expandableContentContainer.setVisibility(View.GONE);
}
}
});
expandableContentContainer.addView(expandableContent);
}
return this;
}
}

View File

@@ -0,0 +1,74 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.util.GradientDrawableBuilder;
import com.bytecat.algui.component.Stack;
import android.graphics.Typeface;
import com.bytecat.algui.layoutparams.StackParams;
import android.view.Gravity;
public class Button extends Stack {
public String buttonText;
public Text text;
private ClickCallback clickCallback;
public Button(String buttonText) {
this.buttonText = buttonText;
setBackground(
new GradientDrawableBuilder()
.setColor(hexColor("#B32C2C32"))
.setAllRadius(dip2px(8))
);
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickCallback != null) {
clickCallback.onClick();
}
}
});
text = new Text()
.setText(buttonText)
.setTextSize(10f)
.setTextColor(hexColor("#FFA5A5A5"))
.setTypeface(Typeface.DEFAULT_BOLD)
.setLayoutParams(
new StackParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setGravity(Gravity.CENTER)
.setMargins(dip2pxInt(15), dip2pxInt(5), dip2pxInt(15), dip2pxInt(5))
);
addView(text);
}
public Button() {
this("button.common.run");
}
public Button setClickCallback(ClickCallback clickCallback) {
this.clickCallback = clickCallback;
return this;
}
}

View File

@@ -0,0 +1,113 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.graphics.Typeface;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import android.widget.RelativeLayout;
import java.io.File;
public class ButtonContent extends Relative {
public static final int BUTTON_ID = View.generateViewId();
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public Button mButton; // 使用 Button
public ButtonContent(String title) {
this(title, null);
}
public ButtonContent(String title, String description) {
this(title, description, false);
}
public ButtonContent(String title, String description, boolean isChecked) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.START_OF, BUTTON_ID)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#FF999999"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
// 初始化 Button
// 初始化 Button
String buttonText = "Run";
String filePath ="/sdcard/Android/data/com.vortex.celestial/files/switch.lang";
File file = new File(filePath);
if (file.exists()) {
buttonText = "执行";
}
mButton = new Button(buttonText); // 可以根据需要修改按钮文本
mButton.setId(BUTTON_ID).setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(mButton);
}
// 添加设置按钮点击回调的方法
public ButtonContent setButtonCallback(ClickCallback clickCallback) {
mButton.setClickCallback(clickCallback);
return this;
}
}

View File

@@ -0,0 +1,113 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.graphics.Typeface;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import android.widget.RelativeLayout;
import java.io.File;
public class ButtonContent extends Relative {
public static final int BUTTON_ID = View.generateViewId();
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public Button mButton; // 使用 Button
public ButtonContent(String title) {
this(title, null);
}
public ButtonContent(String title, String description) {
this(title, description, false);
}
public ButtonContent(String title, String description, boolean isChecked) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.START_OF, BUTTON_ID)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#FF999999"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
// 初始化 Button
// 初始化 Button
String buttonText = "Run";
String filePath ="/sdcard/TC配置文件/switch.lang";
File file = new File(filePath);
if (file.exists()) {
buttonText = "执行";
}
mButton = new Button(buttonText); // 可以根据需要修改按钮文本
mButton.setId(BUTTON_ID).setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(mButton);
}
// 添加设置按钮点击回调的方法
public ButtonContent setButtonCallback(ClickCallback clickCallback) {
mButton.setClickCallback(clickCallback);
return this;
}
}

View File

@@ -0,0 +1,138 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import java.io.File;
public class ButtonContentCard extends ContentCard {
public ButtonContent buttonContent;
public Column expandableContentContainer;
public Widget divider;
public ViewHelper<?> expandableContent;
public boolean isExpanded;
// 中文文本
private String chineseTitle;
private String chineseDescription;
// 英文文本
private String englishTitle;
private String englishDescription;
// 文件路径
private String languageSwitchFilePath;
public ButtonContentCard(String title, String description, boolean isChecked) {
buttonContent = new ButtonContent(title, description, isChecked);
buttonContent.setLayoutParams(
new LinearParams()
.setAllMargins(BaseHelper.dip2pxInt(15))
);
addView(buttonContent);
expandableContentContainer = new Column()
.setVisibility(View.GONE)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(BaseHelper.dip2pxInt(15), 0, BaseHelper.dip2pxInt(15), BaseHelper.dip2pxInt(15))
);
addView(expandableContentContainer);
divider = new Widget()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.dip2pxInt(1))
)
.setBackgroundColor(BaseHelper.hexColor("#B32C2C32"));
expandableContentContainer.addView(divider);
// 初始化时直接设置中文文本
updateTextBasedOnFile();
}
public ButtonContentCard(String title, String description) {
this(title, description, false);
}
public ButtonContentCard(String title) {
this(title, null, false);
}
public ButtonContentCard setClickCallback(ClickCallback clickCallback) {
buttonContent.setButtonCallback(clickCallback);
return this;
}
public ButtonContentCard setExpandableContent(ViewHelper<?> expandableContent) {
this.expandableContent = expandableContent;
if (expandableContent != null) {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (build().getLayoutTransition().isRunning()) {
return;
}
isExpanded = !isExpanded;
if (isExpanded) {
expandableContentContainer.setVisibility(View.VISIBLE);
} else {
expandableContentContainer.setVisibility(View.GONE);
}
}
});
expandableContentContainer.addView(expandableContent);
}
return this;
}
// 设置中英文文本
public ButtonContentCard OText(String chineseTitle, String chineseDescription,
String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
updateTextBasedOnFile();
return this;
}
// 设置语言切换文件路径
public ButtonContentCard setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
if (languageSwitchFilePath == null) return;
boolean fileExists = new File(languageSwitchFilePath).exists();
if (fileExists) {
buttonContent.titleText.setText(chineseTitle);
if (buttonContent.descriptionText != null) {
buttonContent.descriptionText.setText(chineseDescription);
}
} else {
buttonContent.titleText.setText(englishTitle);
if (buttonContent.descriptionText != null) {
buttonContent.descriptionText.setText(englishDescription);
}
}
}
}

View File

@@ -0,0 +1,33 @@
package com.bytecat.algui.ui.component;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.ColumnScroll;
import com.bytecat.algui.layoutparams.LinearParams;
public class CategoryBox extends ColumnScroll {
public Column contentContainer;
public CategoryBox() {
setScrollBarEnabled(false);
setFadingEdgeEnabled(true);
setFadingEdgeLength(dip2pxInt(8));
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.MatchParent)
.setTopMargin(dip2pxInt(10))
.setBottomMargin(dip2pxInt(10))
);
contentContainer = new Column()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
}
}

View File

@@ -0,0 +1,56 @@
package com.bytecat.algui.ui.component;
import android.graphics.Typeface;
import android.view.Gravity;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.component.Row;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
public class CategoryCard extends Row {
private String category;
public Text categoryTitleText;
public ViewHelper<?> content;
public CategoryCard setText(String category) {
this.category = category;
if (categoryTitleText != null) {
categoryTitleText.setText(category);
}
return this;
}
public CategoryCard setContent(ViewHelper<?> content) {
this.content = content;
return this;
}
public CategoryCard() {
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(dip2pxInt(34))
.setMargins(dip2pxInt(15), 0, dip2pxInt(15), 0)
);
categoryTitleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.MatchParent)
)
.setGravity(Gravity.CENTER)
.setText(category)
.setTextSize(12f)
.setTextColor(hexColor("#DAFFFFFF"))
.setTypeface(Typeface.DEFAULT_BOLD);
addView(categoryTitleText);
}
}

View File

@@ -0,0 +1,25 @@
package com.bytecat.algui.ui.component;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.util.GradientDrawableBuilder;
public class ContentCard extends Column {
public ContentCard() {
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(0, dip2pxInt(5), 0, dip2pxInt(5))
);
setBackground(
new GradientDrawableBuilder()
.setColor(hexColor("#20D0D0D0"))
.setAllRadius(dip2px(10))
);
animatedContent();
}
}

View File

@@ -0,0 +1,126 @@
package com.bytecat.algui.ui.component;
import java.util.LinkedHashMap;
import java.util.Map;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.callback.RadioGroupCallback;
import com.bytecat.algui.component.Row;
import com.bytecat.algui.component.RowScroll;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.StackParams;
public class RadioGroup extends RowScroll {
public Map<String, StatefulButton> map = new LinkedHashMap<>();
public Row row;
private RadioGroupCallback radioGroupCallback;
private boolean isEnabled = false;
/* ===== 中英文切换 ===== */
private String languageSwitchFilePath;
public RadioGroup setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
return this;
}
private boolean isChinese() {
return languageSwitchFilePath != null && new java.io.File(languageSwitchFilePath).exists();
}
public RadioGroup addButton(String chineseTitle, String englishTitle, final String id) {
return addButton(isChinese() ? chineseTitle : englishTitle, id);
}
public RadioGroup() {
setScrollBarEnabled(false);
row = new Row()
.setLayoutParams(
new StackParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
);
addView(row);
}
public RadioGroup setChecked(String id) {
StatefulButton statefulButton = map.get(id);
if (statefulButton != null) {
statefulButton.setChecked(true);
for (String key : map.keySet()) {
StatefulButton value = map.get(key);
if (value != null && !key.equals(id)) {
value.setChecked(false);
}
}
}
return this;
}
public RadioGroup setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
return this;
}
public RadioGroup addButton(String title, final String id) {
if (map.containsKey(id)) {
return this;
}
final StatefulButton statefulButton = new StatefulButton(title);
statefulButton.setClickCallback(new ClickCallback() {
@Override
public void onClick() {
if (statefulButton.isChecked || !isEnabled) {
return;
}
setChecked(id);
if (radioGroupCallback != null) {
radioGroupCallback.onChecked(id);
}
}
});
if (!map.isEmpty()) {
statefulButton.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setLeftMargin(dip2pxInt(10))
);
} else {
statefulButton.setChecked(true);
}
map.put(id, statefulButton);
row.addView(statefulButton);
return this;
}
public RadioGroup removeButton(String id) {
if (!map.containsKey(id)) {
return this;
}
StatefulButton statefulButton = map.get(id);
if (statefulButton != null) {
map.remove(id);
row.removeView(statefulButton);
}
return this;
}
public RadioGroup setRadioGroupCallback(RadioGroupCallback radioGroupCallback) {
this.radioGroupCallback = radioGroupCallback;
return this;
}
}

View File

@@ -0,0 +1,106 @@
package com.bytecat.algui.ui.component;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.*;
import com.bytecat.algui.callback.SliderCallback;
import android.graphics.RectF;
import android.animation.ValueAnimator;
import com.bytecat.algui.component.BasicSlider;
import com.bytecat.algui.component.Card;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.layoutparams.StackParams;
import com.bytecat.algui.view.SliderView;
public class Slider extends Card {
public BasicSlider basicSlider;
private boolean isEnabled;
private interface DispatchCallback {
void onDispatch(float newProgress, float oldProgress);
}
public Slider setSliderCallback(SliderCallback sliderCallback) {
basicSlider.setSliderCallback(sliderCallback);
return this;
}
public Slider() {
this(100f, 0f);
}
public Slider(float max, float progress) {
this(max, 0, progress);
}
public Slider(float max, float min, float progress) {
setCardBackgroundColor(hexColor("#B32C2C32"));
setCardElevation(0f);
setRadius(dip2px(10));
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(sp2pxInt(10))
.setTopMargin(dip2pxInt(5))
);
basicSlider = new BasicSlider()
.setLayoutParams(
new StackParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.MatchParent)
)
.setSliderParams(max, min, progress);
addView(basicSlider);
}
public Slider setMax(float max) {
basicSlider.setMax(max);
return this;
}
public Slider setMin(float min) {
basicSlider.setMin(min);
return this;
}
public Slider setProgress(float progress) {
basicSlider.setProgress(progress);
return this;
}
public Slider setSliderParams(float max, float min, float progress) {
basicSlider.setSliderParams(max, min, progress);
return this;
}
public Slider setEnabled(boolean isEnabled) {
if (this.isEnabled != isEnabled) {
this.isEnabled = isEnabled;
final SliderView sliderView = basicSlider.sliderView;
final SliderCallback sliderCallback = sliderView.sliderCallback;
if (sliderCallback != null) {
float progress = basicSlider.sliderView.getProgress();
sliderCallback.onEnabled(isEnabled, progress);
}
}
return this;
}
public Slider setEnabled1(boolean isEnabled) {
basicSlider.setEnabled(isEnabled);
return this;
}
}

View File

@@ -0,0 +1,218 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.animation.AnimatedSet;
import com.bytecat.algui.util.GradientDrawableBuilder;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.interpolator.FastOutSlowInInterpolator;
import com.bytecat.algui.animation.ValueAnimated;
import android.animation.ValueAnimator;
import java.io.File;
public class StatefulButton extends Button {
public static final String UNCHECKED_BACKGROUND_COLOR = "#B34A4A50";
public static final String CHECKED_BACKGROUND_COLOR = "#CC7F7FD5";
public static final String UNCHECKED_TEXT_COLOR = "#B3A9A9B3";
public static final String CHECKED_TEXT_COLOR = "#E6E0E0E6";
public boolean isChecked;
private SwitchCallback switchCallback;
private int currentBackgroundColor;
private int currentTextColor;
public AnimatedSet animatorSet;
private String chineseText;
private String englishText;
private float chineseTextSize = 10f; // 中文文本大小
private float englishTextSize = 10f; // 英文文本大小
private String languageSwitchFilePath;
public StatefulButton(String buttonText, boolean isChecked) {
super(buttonText);
this.isChecked = isChecked;
currentBackgroundColor = BaseHelper.hexColor(isChecked ? CHECKED_BACKGROUND_COLOR : UNCHECKED_BACKGROUND_COLOR);
currentTextColor = BaseHelper.hexColor(isChecked ? CHECKED_TEXT_COLOR : UNCHECKED_TEXT_COLOR);
setBackground(
new GradientDrawableBuilder()
.setColor(currentBackgroundColor)
.setAllRadius(BaseHelper.dip2px(8))
);
text.setTextColor(currentTextColor);
setClickCallback(new ClickCallback() {
@Override
public void onClick() {
if (switchCallback != null && !switchCallback.onChecked(!StatefulButton.this.isChecked)) {
return;
}
animated(!StatefulButton.this.isChecked);
}
});
}
public StatefulButton(String buttonText) {
this(buttonText, false);
}
public StatefulButton() {
this("button.common.run");
}
// 新增构造函数,用于支持中英文标题
public StatefulButton(String chineseText, String englishText, boolean isChecked) {
super(chineseText); // 默认显示中文
this.isChecked = isChecked;
this.chineseText = chineseText;
this.englishText = englishText;
currentBackgroundColor = BaseHelper.hexColor(isChecked ? CHECKED_BACKGROUND_COLOR : UNCHECKED_BACKGROUND_COLOR);
currentTextColor = BaseHelper.hexColor(isChecked ? CHECKED_TEXT_COLOR : UNCHECKED_TEXT_COLOR);
setBackground(
new GradientDrawableBuilder()
.setColor(currentBackgroundColor)
.setAllRadius(BaseHelper.dip2px(8))
);
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setLeftMargin(dip2pxInt(10))
);
text.setTextColor(currentTextColor);
// 设置中文文本大小
text.setTextSize(chineseTextSize);
// 设置语言切换文件路径
languageSwitchFilePath = "/sdcard/Android/data/com.vortex.celestial/files/switch.lang";
// 检查语言文件存在与否并更新文本
updateTextBasedOnFile();
setClickCallback(new ClickCallback() {
@Override
public void onClick() {
if (switchCallback != null && !switchCallback.onChecked(!StatefulButton.this.isChecked)) {
return;
}
animated(!StatefulButton.this.isChecked);
}
});
}
public StatefulButton setChecked(boolean isChecked) {
if (this.isChecked != isChecked) {
animated(isChecked);
}
return this;
}
public StatefulButton setSwitchCallback(SwitchCallback switchCallback) {
this.switchCallback = switchCallback;
return this;
}
private void animated(boolean isChecked) {
if (animatorSet != null && animatorSet.build().isRunning()) {
animatorSet.cancel();
}
this.isChecked = isChecked;
int endBackgroundColor;
if (this.isChecked) {
endBackgroundColor = BaseHelper.hexColor(CHECKED_BACKGROUND_COLOR);
} else {
endBackgroundColor = BaseHelper.hexColor(UNCHECKED_BACKGROUND_COLOR);
}
int endTextColor;
if (this.isChecked) {
endTextColor = BaseHelper.hexColor(CHECKED_TEXT_COLOR);
} else {
endTextColor = BaseHelper.hexColor(UNCHECKED_TEXT_COLOR);
}
animatorSet = new AnimatedSet()
.setInterpolator(new FastOutSlowInInterpolator())
.setDuration(100L)
.playTogether(
new ValueAnimated()
.ofArgb(currentBackgroundColor, endBackgroundColor)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
setBackground(
new GradientDrawableBuilder()
.setColor(animatedValue)
.setAllRadius(BaseHelper.dip2px(8))
);
currentBackgroundColor = animatedValue;
}
}),
new ValueAnimated()
.ofArgb(currentTextColor, endTextColor)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
text.setTextColor(animatedValue);
currentTextColor = animatedValue;
}
})
)
.start();
}
// 设置语言切换文件路径
public StatefulButton setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
if (languageSwitchFilePath == null) return;
boolean fileExists = new File(languageSwitchFilePath).exists();
if (fileExists) {
text.setText(chineseText);
text.setTextSize(chineseTextSize);
// 设置中文按钮内间距
} else {
text.setText(englishText);
text.setTextSize(englishTextSize);
// 设置英文按钮内间距(更小)
}
}
}

View File

@@ -0,0 +1,218 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.animation.AnimatedSet;
import com.bytecat.algui.util.GradientDrawableBuilder;
import com.bytecat.algui.callback.ClickCallback;
import com.bytecat.algui.interpolator.FastOutSlowInInterpolator;
import com.bytecat.algui.animation.ValueAnimated;
import android.animation.ValueAnimator;
import java.io.File;
public class StatefulButton extends Button {
public static final String UNCHECKED_BACKGROUND_COLOR = "#B34A4A50";
public static final String CHECKED_BACKGROUND_COLOR = "#CC7F7FD5";
public static final String UNCHECKED_TEXT_COLOR = "#B3A9A9B3";
public static final String CHECKED_TEXT_COLOR = "#E6E0E0E6";
public boolean isChecked;
private SwitchCallback switchCallback;
private int currentBackgroundColor;
private int currentTextColor;
public AnimatedSet animatorSet;
private String chineseText;
private String englishText;
private float chineseTextSize = 10f; // 中文文本大小
private float englishTextSize = 10f; // 英文文本大小
private String languageSwitchFilePath;
public StatefulButton(String buttonText, boolean isChecked) {
super(buttonText);
this.isChecked = isChecked;
currentBackgroundColor = BaseHelper.hexColor(isChecked ? CHECKED_BACKGROUND_COLOR : UNCHECKED_BACKGROUND_COLOR);
currentTextColor = BaseHelper.hexColor(isChecked ? CHECKED_TEXT_COLOR : UNCHECKED_TEXT_COLOR);
setBackground(
new GradientDrawableBuilder()
.setColor(currentBackgroundColor)
.setAllRadius(BaseHelper.dip2px(8))
);
text.setTextColor(currentTextColor);
setClickCallback(new ClickCallback() {
@Override
public void onClick() {
if (switchCallback != null && !switchCallback.onChecked(!StatefulButton.this.isChecked)) {
return;
}
animated(!StatefulButton.this.isChecked);
}
});
}
public StatefulButton(String buttonText) {
this(buttonText, false);
}
public StatefulButton() {
this("button.common.run");
}
// 新增构造函数,用于支持中英文标题
public StatefulButton(String chineseText, String englishText, boolean isChecked) {
super(chineseText); // 默认显示中文
this.isChecked = isChecked;
this.chineseText = chineseText;
this.englishText = englishText;
currentBackgroundColor = BaseHelper.hexColor(isChecked ? CHECKED_BACKGROUND_COLOR : UNCHECKED_BACKGROUND_COLOR);
currentTextColor = BaseHelper.hexColor(isChecked ? CHECKED_TEXT_COLOR : UNCHECKED_TEXT_COLOR);
setBackground(
new GradientDrawableBuilder()
.setColor(currentBackgroundColor)
.setAllRadius(BaseHelper.dip2px(8))
);
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setLeftMargin(dip2pxInt(10))
);
text.setTextColor(currentTextColor);
// 设置中文文本大小
text.setTextSize(chineseTextSize);
// 设置语言切换文件路径
languageSwitchFilePath = "/sdcard/TC配置文件/switch.lang";
// 检查语言文件存在与否并更新文本
updateTextBasedOnFile();
setClickCallback(new ClickCallback() {
@Override
public void onClick() {
if (switchCallback != null && !switchCallback.onChecked(!StatefulButton.this.isChecked)) {
return;
}
animated(!StatefulButton.this.isChecked);
}
});
}
public StatefulButton setChecked(boolean isChecked) {
if (this.isChecked != isChecked) {
animated(isChecked);
}
return this;
}
public StatefulButton setSwitchCallback(SwitchCallback switchCallback) {
this.switchCallback = switchCallback;
return this;
}
private void animated(boolean isChecked) {
if (animatorSet != null && animatorSet.build().isRunning()) {
animatorSet.cancel();
}
this.isChecked = isChecked;
int endBackgroundColor;
if (this.isChecked) {
endBackgroundColor = BaseHelper.hexColor(CHECKED_BACKGROUND_COLOR);
} else {
endBackgroundColor = BaseHelper.hexColor(UNCHECKED_BACKGROUND_COLOR);
}
int endTextColor;
if (this.isChecked) {
endTextColor = BaseHelper.hexColor(CHECKED_TEXT_COLOR);
} else {
endTextColor = BaseHelper.hexColor(UNCHECKED_TEXT_COLOR);
}
animatorSet = new AnimatedSet()
.setInterpolator(new FastOutSlowInInterpolator())
.setDuration(100L)
.playTogether(
new ValueAnimated()
.ofArgb(currentBackgroundColor, endBackgroundColor)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
setBackground(
new GradientDrawableBuilder()
.setColor(animatedValue)
.setAllRadius(BaseHelper.dip2px(8))
);
currentBackgroundColor = animatedValue;
}
}),
new ValueAnimated()
.ofArgb(currentTextColor, endTextColor)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
text.setTextColor(animatedValue);
currentTextColor = animatedValue;
}
})
)
.start();
}
// 设置语言切换文件路径
public StatefulButton setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
if (languageSwitchFilePath == null) return;
boolean fileExists = new File(languageSwitchFilePath).exists();
if (fileExists) {
text.setText(chineseText);
text.setTextSize(chineseTextSize);
// 设置中文按钮内间距
} else {
text.setText(englishText);
text.setTextSize(englishTextSize);
// 设置英文按钮内间距(更小)
}
}
}

View File

@@ -0,0 +1,146 @@
package com.bytecat.algui.ui.component;
import android.animation.ValueAnimator;
import android.view.View;
import com.bytecat.algui.animation.AnimatedSet;
import com.bytecat.algui.animation.ValueAnimated;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Stack;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.interpolator.FastOutSlowInInterpolator;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.StackParams;
import com.bytecat.algui.util.GradientDrawableBuilder;
public class Switch extends Stack {
public static final String UNCHECKED_COLOR = "#B34A4A50";
//UNCHECKED_COLOR = "#B34A4A50"; // 70 % 不透冷灰
//CHECKED_COLOR = "#CC7F7FD5"; // 80 % 不透淡紫
//circleColor = "#E6E0E0E6"; // 90 % 不透雾白
public static final String CHECKED_COLOR = "#CC7F7FD5";
public boolean isChecked;
public int currentBackgroundColor;
public Widget circle;
public AnimatedSet animatorSet;
private SwitchCallback switchCallback;
public Switch() {
this(false);
}
public Switch(boolean isChecked) {
this.isChecked = isChecked;
setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
);
currentBackgroundColor = hexColor(isChecked ? CHECKED_COLOR : UNCHECKED_COLOR);
setBackground(
new GradientDrawableBuilder()
.setColor(currentBackgroundColor)
.setAllRadius(dip2px(30))
);
circle = new Widget()
.setTranslationX(isChecked ? dip2px(10) : -dip2px(10))
.setBackground(
new GradientDrawableBuilder()
.setColor(hexColor("#E6E0E0E6"))
.setAllRadius(dip2px(15))
)
.setLayoutParams(
new StackParams()
.setWidth(dip2pxInt(12))
.setHeight(dip2pxInt(12))
.setMargins(dip2pxInt(15), dip2pxInt(5), dip2pxInt(15), dip2pxInt(5))
);
addView(circle);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (switchCallback != null && !switchCallback.onChecked(!Switch.this.isChecked)) {
return;
}
animated(!Switch.this.isChecked);
}
});
}
public Switch setChecked(boolean isChecked) {
if (this.isChecked != isChecked) {
animated(isChecked);
}
return this;
}
public Switch setSwitchCallback(SwitchCallback switchCallback) {
this.switchCallback = switchCallback;
return this;
}
private void animated(boolean isChecked) {
if (animatorSet != null && animatorSet.build().isRunning()) {
animatorSet.cancel();
}
this.isChecked = isChecked;
float endX;
if (this.isChecked) {
endX = dip2px(10);
} else {
endX = -dip2px(10);
}
int endColor;
if (this.isChecked) {
endColor = hexColor(CHECKED_COLOR);
} else {
endColor = hexColor(UNCHECKED_COLOR);
}
animatorSet = new AnimatedSet()
.setInterpolator(new FastOutSlowInInterpolator())
.setDuration(200L)
.playTogether(
new ValueAnimated()
.ofFloat(circle.build().getTranslationX(), endX)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
circle.setTranslationX(animatedValue);
}
}),
new ValueAnimated()
.ofArgb(currentBackgroundColor, endColor)
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
setBackground(
new GradientDrawableBuilder()
.setColor(animatedValue)
.setAllRadius(dip2px(30))
);
currentBackgroundColor = animatedValue;
}
})
)
.start();
}
}

View File

@@ -0,0 +1,165 @@
package com.bytecat.algui.ui.component;
import android.graphics.Typeface;
import android.view.View;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import java.io.File;
public class SwitchContent extends Relative {
public static final String DEFAULT_LANGUAGE_SWITCH_FILE_PATH =
"/sdcard/Android/data/com.vortex.celestial/files/switch.lang";
public static final int SWITCH_ID = View.generateViewId();
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public Switch mSwitch;
// 中文文本
private String chineseTitle;
private String chineseDescription;
// 英文文本
private String englishTitle;
private String englishDescription;
// 文件路径
private String languageSwitchFilePath;
public SwitchContent(String title) {
this(title, null);
}
public SwitchContent(String title, String description) {
this(title, description, false);
}
public SwitchContent(String title, String description, boolean isChecked) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.START_OF, SWITCH_ID)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#DAFFFFFF"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
mSwitch = new Switch(isChecked);
mSwitch.setId(SWITCH_ID).setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(mSwitch);
updateTextBasedOnFile();
}
public boolean newState() {
return false;
}
public SwitchContent setChecked(boolean isChecked) {
mSwitch.setChecked(isChecked);
return this;
}
public SwitchContent setSwitchCallback(SwitchCallback switchCallback) {
mSwitch.setSwitchCallback(switchCallback);
return this;
}
// 设置中英文文本
public SwitchContent OText(String chineseTitle, String chineseDescription, String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
return this;
}
// 设置语言切换文件路径
public SwitchContent setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
// 1. 取自定义路径,没有则用默认路径
String path = languageSwitchFilePath != null
? languageSwitchFilePath
: DEFAULT_LANGUAGE_SWITCH_FILE_PATH;
// 2. 如果中英文都未设置,直接 return避免 NPE
if (chineseTitle == null && englishTitle == null) return;
boolean fileExists = new File(path).exists();
// 3. 选择对应语言
String titleTarget = fileExists ? chineseTitle : englishTitle;
String descTarget = fileExists ? chineseDescription : englishDescription;
if (titleTarget != null) titleText.setText(titleTarget);
if (descriptionText != null && descTarget != null) {
descriptionText.setText(descTarget);
}
}
}

View File

@@ -0,0 +1,165 @@
package com.bytecat.algui.ui.component;
import android.graphics.Typeface;
import android.view.View;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
import java.io.File;
public class SwitchContent extends Relative {
public static final String DEFAULT_LANGUAGE_SWITCH_FILE_PATH =
"/sdcard/TC配置文件/switch.lang";
public static final int SWITCH_ID = View.generateViewId();
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public Switch mSwitch;
// 中文文本
private String chineseTitle;
private String chineseDescription;
// 英文文本
private String englishTitle;
private String englishDescription;
// 文件路径
private String languageSwitchFilePath;
public SwitchContent(String title) {
this(title, null);
}
public SwitchContent(String title, String description) {
this(title, description, false);
}
public SwitchContent(String title, String description, boolean isChecked) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.START_OF, SWITCH_ID)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#DAFFFFFF"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
mSwitch = new Switch(isChecked);
mSwitch.setId(SWITCH_ID).setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(mSwitch);
updateTextBasedOnFile();
}
public boolean newState() {
return false;
}
public SwitchContent setChecked(boolean isChecked) {
mSwitch.setChecked(isChecked);
return this;
}
public SwitchContent setSwitchCallback(SwitchCallback switchCallback) {
mSwitch.setSwitchCallback(switchCallback);
return this;
}
// 设置中英文文本
public SwitchContent OText(String chineseTitle, String chineseDescription, String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
return this;
}
// 设置语言切换文件路径
public SwitchContent setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
// 1. 取自定义路径,没有则用默认路径
String path = languageSwitchFilePath != null
? languageSwitchFilePath
: DEFAULT_LANGUAGE_SWITCH_FILE_PATH;
// 2. 如果中英文都未设置,直接 return避免 NPE
if (chineseTitle == null && englishTitle == null) return;
boolean fileExists = new File(path).exists();
// 3. 选择对应语言
String titleTarget = fileExists ? chineseTitle : englishTitle;
String descTarget = fileExists ? chineseDescription : englishDescription;
if (titleTarget != null) titleText.setText(titleTarget);
if (descriptionText != null && descTarget != null) {
descriptionText.setText(descTarget);
}
}
}

View File

@@ -0,0 +1,174 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import java.io.File;
public class SwitchContentCard extends ContentCard {
public SwitchContent switchContent;
public Column expandableContentContainer;
// 统一默认语言切换文件路径
private static final String DEFAULT_LANGUAGE_SWITCH_FILE_PATH = "/sdcard/Android/data/com.vortex.celestial/files/switch.lang";
public Widget divider;
public ViewHelper<?> expandableContent;
public boolean isExpanded;
// 中文文本
private String chineseTitle;
private String chineseDescription;
// 英文文本
private String englishTitle;
private String englishDescription;
// 文件路径
private String languageSwitchFilePath;
public SwitchContentCard(String title, String description, boolean isChecked) {
switchContent = new SwitchContent(title, description, isChecked);
switchContent.setLayoutParams(
new LinearParams()
.setAllMargins(dip2pxInt(15))
);
addView(switchContent);
expandableContentContainer = new Column()
.setVisibility(View.GONE)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(dip2pxInt(15), 0, dip2pxInt(15), dip2pxInt(15))
);
addView(expandableContentContainer);
divider = new Widget()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(dip2pxInt(1))
)
.setBackgroundColor(hexColor("#40D0D0D0"));
expandableContentContainer.addView(divider);
// ↓↓↓ 自动使用统一路径刷新文本
updateTextBasedOnFile();
}
public SwitchContentCard(String title, String description) {
this(title, description, false);
}
public SwitchContentCard(String title) {
this(title, null, false);
}
public void setClickCallback(Object onClick) {
}
public SwitchContentCard setExpandableContent(ViewHelper<?> expandableContent) {
this.expandableContent = expandableContent;
if (expandableContent != null) {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (build().getLayoutTransition().isRunning()) {
return;
}
isExpanded = !isExpanded;
if (isExpanded) {
expandableContentContainer.setVisibility(View.VISIBLE);
} else {
expandableContentContainer.setVisibility(View.GONE);
}
}
});
expandableContentContainer.addView(expandableContent);
}
return this;
}
public SwitchContentCard setSwitchCallback(SwitchCallback switchCallback) {
switchContent.setSwitchCallback(switchCallback);
return this;
}
public SwitchContentCard setChecked(boolean isChecked) {
switchContent.setChecked(isChecked);
return this;
}
// 设置中英文文本
public SwitchContentCard OText(String chineseTitle, String chineseDescription,
String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
updateTextBasedOnFile();
return this;
}
// 只设置中文文本
public SwitchContentCard OText(String chineseTitle, String chineseDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
return this;
}
// 设置语言切换文件路径
public SwitchContentCard setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
// 用实例路径,没有则用统一路径
String path = languageSwitchFilePath != null ? languageSwitchFilePath
: DEFAULT_LANGUAGE_SWITCH_FILE_PATH;
boolean fileExists = new java.io.File(path).exists();
String titleTarget = fileExists ? chineseTitle : englishTitle;
String descTarget = fileExists ? chineseDescription : englishDescription;
if (titleTarget != null) switchContent.titleText.setText(titleTarget);
if (switchContent.descriptionText != null && descTarget != null) {
switchContent.descriptionText.setText(descTarget);
}
}
// 保留原有的构造方式
public static SwitchContentCard create(String title, String description, boolean isChecked) {
return new SwitchContentCard(title, description, isChecked);
}
public static SwitchContentCard create(String title, String description) {
return new SwitchContentCard(title, description);
}
public static SwitchContentCard create(String title) {
return new SwitchContentCard(title);
}
}

View File

@@ -0,0 +1,174 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.callback.SwitchCallback;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
import java.io.File;
public class SwitchContentCard extends ContentCard {
public SwitchContent switchContent;
public Column expandableContentContainer;
// 统一默认语言切换文件路径
private static final String DEFAULT_LANGUAGE_SWITCH_FILE_PATH = "/sdcard/TC配置文件/switch.lang";
public Widget divider;
public ViewHelper<?> expandableContent;
public boolean isExpanded;
// 中文文本
private String chineseTitle;
private String chineseDescription;
// 英文文本
private String englishTitle;
private String englishDescription;
// 文件路径
private String languageSwitchFilePath;
public SwitchContentCard(String title, String description, boolean isChecked) {
switchContent = new SwitchContent(title, description, isChecked);
switchContent.setLayoutParams(
new LinearParams()
.setAllMargins(dip2pxInt(15))
);
addView(switchContent);
expandableContentContainer = new Column()
.setVisibility(View.GONE)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(dip2pxInt(15), 0, dip2pxInt(15), dip2pxInt(15))
);
addView(expandableContentContainer);
divider = new Widget()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(dip2pxInt(1))
)
.setBackgroundColor(hexColor("#40D0D0D0"));
expandableContentContainer.addView(divider);
// ↓↓↓ 自动使用统一路径刷新文本
updateTextBasedOnFile();
}
public SwitchContentCard(String title, String description) {
this(title, description, false);
}
public SwitchContentCard(String title) {
this(title, null, false);
}
public void setClickCallback(Object onClick) {
}
public SwitchContentCard setExpandableContent(ViewHelper<?> expandableContent) {
this.expandableContent = expandableContent;
if (expandableContent != null) {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (build().getLayoutTransition().isRunning()) {
return;
}
isExpanded = !isExpanded;
if (isExpanded) {
expandableContentContainer.setVisibility(View.VISIBLE);
} else {
expandableContentContainer.setVisibility(View.GONE);
}
}
});
expandableContentContainer.addView(expandableContent);
}
return this;
}
public SwitchContentCard setSwitchCallback(SwitchCallback switchCallback) {
switchContent.setSwitchCallback(switchCallback);
return this;
}
public SwitchContentCard setChecked(boolean isChecked) {
switchContent.setChecked(isChecked);
return this;
}
// 设置中英文文本
public SwitchContentCard OText(String chineseTitle, String chineseDescription,
String englishTitle, String englishDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
this.englishTitle = englishTitle;
this.englishDescription = englishDescription;
updateTextBasedOnFile();
return this;
}
// 只设置中文文本
public SwitchContentCard OText(String chineseTitle, String chineseDescription) {
this.chineseTitle = chineseTitle;
this.chineseDescription = chineseDescription;
return this;
}
// 设置语言切换文件路径
public SwitchContentCard setLanguageSwitchFilePath(String filePath) {
this.languageSwitchFilePath = filePath;
updateTextBasedOnFile();
return this;
}
// 根据文件存在与否更新文本
private void updateTextBasedOnFile() {
// 用实例路径,没有则用统一路径
String path = languageSwitchFilePath != null ? languageSwitchFilePath
: DEFAULT_LANGUAGE_SWITCH_FILE_PATH;
boolean fileExists = new java.io.File(path).exists();
String titleTarget = fileExists ? chineseTitle : englishTitle;
String descTarget = fileExists ? chineseDescription : englishDescription;
if (titleTarget != null) switchContent.titleText.setText(titleTarget);
if (switchContent.descriptionText != null && descTarget != null) {
switchContent.descriptionText.setText(descTarget);
}
}
// 保留原有的构造方式
public static SwitchContentCard create(String title, String description, boolean isChecked) {
return new SwitchContentCard(title, description, isChecked);
}
public static SwitchContentCard create(String title, String description) {
return new SwitchContentCard(title, description);
}
public static SwitchContentCard create(String title) {
return new SwitchContentCard(title);
}
}

View File

@@ -0,0 +1,84 @@
package com.bytecat.algui.ui.component;
import android.graphics.Typeface;
import android.widget.RelativeLayout;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Relative;
import com.bytecat.algui.component.Text;
import com.bytecat.algui.layoutparams.LinearParams;
import com.bytecat.algui.layoutparams.RelativeParams;
public class TextContent extends Relative {
public final String title;
public final String description;
public Relative contentContainer;
public Column textContainer;
public Text titleText;
public Text descriptionText;
public TextContent(String title) {
this(title, null);
}
public TextContent(String title, String description) {
this.title = title;
this.description = description;
contentContainer = new Relative()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
);
addView(contentContainer);
textContainer = new Column()
.setLayoutParams(
new RelativeParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setRightMargin(dip2pxInt(15))
.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
.addRule(RelativeLayout.CENTER_IN_PARENT)
);
contentContainer.addView(textContainer);
titleText = new Text()
.setSingleLine(true)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
)
.setText(title)
.setTextSize(12f)
.setTextColor(hexColor("#FF999999"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(titleText);
if (description != null) {
descriptionText = new Text()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.WrapContent)
.setHeight(BaseHelper.WrapContent)
.setTopMargin(dip2pxInt(2))
)
.setText(description)
.setTextSize(10f)
.setTextColor(hexColor("#FFC5C5C5"))
.setTypeface(Typeface.DEFAULT_BOLD);
textContainer.addView(descriptionText);
}
}
}

View File

@@ -0,0 +1,78 @@
package com.bytecat.algui.ui.component;
import android.view.View;
import com.bytecat.algui.base.BaseHelper;
import com.bytecat.algui.base.ViewHelper;
import com.bytecat.algui.component.Column;
import com.bytecat.algui.component.Widget;
import com.bytecat.algui.layoutparams.LinearParams;
public class TextContentCard extends ContentCard {
public TextContent textContent;
public Column expandableContentContainer;
public Widget divider;
public ViewHelper<?> expandableContent;
public boolean isExpanded;
public TextContentCard(String title, String description) {
textContent = new TextContent(title, description);
textContent.setLayoutParams(
new LinearParams()
.setAllMargins(dip2pxInt(15))
);
addView(textContent);
expandableContentContainer = new Column()
.setVisibility(View.GONE)
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(BaseHelper.WrapContent)
.setMargins(dip2pxInt(15), 0, dip2pxInt(15), dip2pxInt(15))
);
addView(expandableContentContainer);
divider = new Widget()
.setLayoutParams(
new LinearParams()
.setWidth(BaseHelper.MatchParent)
.setHeight(dip2pxInt(1))
)
.setBackgroundColor(hexColor("#40D0D0D0"));
expandableContentContainer.addView(divider);
}
public TextContentCard(String title) {
this(title, null);
}
public TextContentCard setExpandableContent(ViewHelper<?> expandableContent) {
this.expandableContent = expandableContent;
if (expandableContent != null) {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (build().getLayoutTransition().isRunning()) {
return;
}
isExpanded = !isExpanded;
if (isExpanded) {
expandableContentContainer.setVisibility(View.VISIBLE);
} else {
expandableContentContainer.setVisibility(View.GONE);
}
}
});
expandableContentContainer.addView(expandableContent);
}
return this;
}
}