我是中原工学院的楚琼涛鸿蒙大作业如下:
一、效果运行截图
二、代码实现
1.方格实体类
package com.common.myapplication.bean;
import ohos.media.image.PixelMap;
/**
* 每个方格实体类
*/
public class ImgSliceBean {
private PixelMap pixelMap;//每个小图片
private int index; //每个小图片的位置
private boolean isBlank = false;//是否是空格
public PixelMap getPixelMap() {
return pixelMap;
}
public void setPixelMap(PixelMap pixelMap) {
this.pixelMap = pixelMap;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public boolean isBlank() {
return isBlank;
}
public void setBlank(boolean blank) {
isBlank = blank;
}
@Override
public String toString() {
return "ImgSliceBean{" +
"pixelMap=" + pixelMap +
", index=" + index +
'}';
}
}
2.自定义对话框按钮颜色元素
package com.common.myapplication;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.ComponentState;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.app.Context;
/**
* 自定义对话框按钮颜色元素
*/
public class GeneralButtonElement extends StateElement {
private Context mContext;//上下文对象
private int[] mStateFlagEmpty = new int[]{ComponentState.COMPONENT_STATE_EMPTY};
private int[] mStateFlagPressed = new int[]{ComponentState.COMPONENT_STATE_PRESSED};
private int[][] mAllTypeColorIds = {//颜色集合
{
ResourceTable.Color_colorNormal, ResourceTable.Color_colorNormalPressed
},
{
ResourceTable.Color_colorAccent, ResourceTable.Color_colorAccentPressed
},
{
ResourceTable.Color_colorError, ResourceTable.Color_colorErrorPressed
}
};
public static final int TYPE_NORMAL = 0;
public static final int TYPE_ACCENT = 1;
public static final int TYPE_ERROR = 2;
public GeneralButtonElement(Context context, int type) {
super();
mContext = context;
initBackground(mAllTypeColorIds[type]);
}
private void initBackground(int[] colorIds) {
this.addState(mStateFlagPressed, new ShapeElement() {
{
setRgbColor(RgbColor.fromArgbInt(ResourceTool.getColor(mContext, colorIds[1], 0)));
setCornerRadius(ResourceTool.getFloat(mContext, ResourceTable.Float_dialog_corner_radius, 0));
}
});
this.addState(mStateFlagEmpty, new ShapeElement() {
{
setRgbColor(RgbColor.fromArgbInt(ResourceTool.getColor(mContext, colorIds[0], 0)));
setCornerRadius(ResourceTool.getFloat(mContext, ResourceTable.Float_dialog_corner_radius, 0));
}
});
}
}
3.主要代码
package com.common.myapplication.slice;
import com.common.myapplication.GeneralButtonElement;
import com.common.myapplication.GeneralDialog;
import com.common.myapplication.ResourceTable;
import com.common.myapplication.bean.ImgSliceBean;
import com.common.myapplication.provider.SampleItemProvider;
import com.common.myapplication.utils.ToastUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;
import java.io.FileDescriptor;
import java.util.*;
public class MainAbilitySlice extends AbilitySlice {
private final int ROW_NUM = 3; //行数
private final int COL_NUM = 3;//列数
private final ImgSliceBean[] pms = new ImgSliceBean[ROW_NUM * COL_NUM];//方格实体类
private final Image[] ivImgs = new Image[COL_NUM * COL_NUM];//图像容器数组
private final Text[] ivIndex = new Text[COL_NUM * COL_NUM];//文本组件数组
private int blandIndex = ROW_NUM * COL_NUM - 1;//空白格子索引
private Uri uri;//图片路径
private Timer timer; //计时器
private TimerTask timerTask;//计时器
private Text tvTimer;//显示倒计时
private long time; //倒计时时长 分钟
private boolean hasPic = false;//是否选中了图片
private boolean isGaming = false;//是否进行中
private ListContainer listContainer; //图片选择列表
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
tvTimer = (Text) findComponentById(ResourceTable.Id_tvTimer);
//初始化图片组件控件和监听事件
ivImgs[0] = (Image) findComponentById(ResourceTable.Id_ivImg0);
ivImgs[0].setClickedListener(component -> handleClick(0));
ivImgs[1] = (Image) findComponentById(ResourceTable.Id_ivImg1);
ivImgs[1].setClickedListener(component -> handleClick(1));
ivImgs[2] = (Image) findComponentById(ResourceTable.Id_ivImg2);
ivImgs[2].setClickedListener(component -> handleClick(2));
ivImgs[3] = (Image) findComponentById(ResourceTable.Id_ivImg3);
ivImgs[3].setClickedListener(component -> handleClick(3));
ivImgs[4] = (Image) findComponentById(ResourceTable.Id_ivImg4);
ivImgs[4].setClickedListener(component -> handleClick(4));
ivImgs[5] = (Image) findComponentById(ResourceTable.Id_ivImg5);
ivImgs[5].setClickedListener(component -> handleClick(5));
ivImgs[6] = (Image) findComponentById(ResourceTable.Id_ivImg6);
ivImgs[6].setClickedListener(component -> handleClick(6));
ivImgs[7] = (Image) findComponentById(ResourceTable.Id_ivImg7);
ivImgs[7].setClickedListener(component -> handleClick(7));
ivImgs[8] = (Image) findComponentById(ResourceTable.Id_ivImg8);
ivImgs[8].setClickedListener(component -> handleClick(8));
//初始化每个放个的文字
ivIndex[0] = (Text) findComponentById(ResourceTable.Id_tvIndex0);
ivIndex[1] = (Text) findComponentById(ResourceTable.Id_tvIndex1);
ivIndex[2] = (Text) findComponentById(ResourceTable.Id_tvIndex2);
ivIndex[3] = (Text) findComponentById(ResourceTable.Id_tvIndex3);
ivIndex[4] = (Text) findComponentById(ResourceTable.Id_tvIndex4);
ivIndex[5] = (Text) findComponentById(ResourceTable.Id_tvIndex5);
ivIndex[6] = (Text) findComponentById(ResourceTable.Id_tvIndex6);
ivIndex[7] = (Text) findComponentById(ResourceTable.Id_tvIndex7);
ivIndex[8] = (Text) findComponentById(ResourceTable.Id_tvIndex8);
initListContainer();
//默认隐藏文字
for (Text index : ivIndex) {
index.setVisibility(Component.HIDE);
}
//开始按钮
Button btnStart = (Button) findComponentById(ResourceTable.Id_btnStart);
btnStart.setClickedListener(component -> {
if (!hasPic) {
ToastUtils.show(getContext(), "请选择图片");
return;
}
if (isGaming) {
ToastUtils.show(getContext(), "进行中。。。");
return;
}
isGaming = true;
List<Integer> sortArr = new ArrayList<>();
for (int i = 0; i < ROW_NUM * COL_NUM - 1; i++) {
sortArr.add(i);
}
Collections.shuffle(sortArr);
sortArr.add(ROW_NUM * COL_NUM - 1);
System.out.println(">>>>>>sortArr>>>>>>>>>>>" + sortArr);
for (int i = 0; i < pms.length; i++) {
ImgSliceBean sliceBean = pms[i];
pms[i] = pms[sortArr.get(i)];
pms[sortArr.get(i)] = sliceBean;
}
for (int i = 0; i < pms.length; i++) {
if (pms[i].isBlank()) {
ivImgs[i].setPixelMap(null);
ivIndex[i].setVisibility(Component.HIDE);
} else {
//设置图片控件对应的位图
ivImgs[i].setPixelMap(pms[i].getPixelMap());
ivIndex[i].setText(pms[i].getIndex() + "");
}
System.out.println(">>>>>>pms>>>>>>>>>>>" + pms[i]);
}
// time = 1 * 60;
time = 0;
timer = new Timer();
// 创建定时器任务
timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("Hello world!");
time++;
long hour = time / 60 / 60;
long mine = time / 60;
long sec = time % 60;
String leftTime = (hour < 10 ? "0" + hour : hour) + ":" +
(mine < 10 ? "0" + mine : mine) + ":" +
(sec < 10 ? "0" + sec : sec);
getMainTaskDispatcher().asyncDispatch(() -> tvTimer.setText("" + leftTime));
if (time == 0) {
isGaming = false;
timer.cancel();
System.out.println(">>>>>时间到>>>>>>>");
getMainTaskDispatcher().syncDispatch(() -> {
GeneralDialog.Builder builder = new GeneralDialog.Builder(getAbility());
builder.setTitle("消息提示")
.setContent("游戏结束!")
.addButton("确定", GeneralButtonElement.TYPE_NORMAL, dialog -> {
dialog.remove();
initPicData();
})
.create()
.show();
});
}
}
};
timer.schedule(timerTask, 0, 1000); // 1秒后执行一次
});
//结束按钮
Button btnEnd = (Button) findComponentById(ResourceTable.Id_btnEnd);
btnEnd.setClickedListener(component -> {
if (!isGaming) {
ToastUtils.show(getContext(), "尚未开始");
return;
}
System.out.println(">>>>>m马上结束>>>>>>>");
GeneralDialog.Builder builder = new GeneralDialog.Builder(getAbility());
builder.setTitle("消息提示")
.setContent("是否确认现在结束?")
.addButton("取消", GeneralButtonElement.TYPE_NORMAL, GeneralDialog::remove)
.addButton("确定", GeneralButtonElement.TYPE_ACCENT, dialog -> {
dialog.remove();
if (timer != null) {
timerTask.cancel();
timer.cancel();
}
isGaming = false;
blandIndex = COL_NUM * ROW_NUM - 1;
initPicData();
})
.create()
.show();
});
}
/**
* 处理方格的点击事件
*/
private void handleClick(int position) {
if (!isGaming) {
ToastUtils.show(getContext(), "请开始游戏");
return;
}
int i = position / ROW_NUM, i1 = position % ROW_NUM;
if (pms[position].isBlank()) {
return;
}
int ibx = blandIndex / COL_NUM, iby = blandIndex % ROW_NUM;
//必须在同一维度
if (i != ibx && i1 != iby) {
return;
}
if (i == ibx) {
if (Math.abs(iby - i1) == 1) {
swapItem(i, i1);
}
}
if (i1 == iby) {
if (Math.abs(ibx - i) == 1) {
swapItem(i, i1);
}
}
}
private void swapItem(int i, int i1) {
//点击的方格和空白格子交换
int ibx = blandIndex / COL_NUM, iby = blandIndex % ROW_NUM;
ImgSliceBean tmp = pms[i * COL_NUM + i1];
pms[i * COL_NUM + i1] = pms[ibx * COL_NUM + iby];
pms[ibx * COL_NUM + iby] = tmp;
pms[i * COL_NUM + i1].setBlank(true);
pms[ibx * COL_NUM + iby].setBlank(false);
ivImgs[i * COL_NUM + i1].setPixelMap(null);
ivIndex[i * COL_NUM + i1].setText("");
ivIndex[i * COL_NUM + i1].setVisibility(Component.HIDE);
ivImgs[ibx * COL_NUM + iby].setPixelMap(pms[ibx * COL_NUM + iby].getPixelMap());
ivIndex[ibx * COL_NUM + iby].setText(pms[ibx * COL_NUM + iby].getIndex() + "");
ivIndex[ibx * COL_NUM + iby].setVisibility(Component.VISIBLE);
//检查是否结束
blandIndex = i * COL_NUM + i1;
boolean b = checkFinish();
System.out.println(">>>>>是否成功>>>>>>>" + b);
if (b) {
//成功则弹出对话框
isGaming = false;
if (timer != null) {
timerTask.cancel();
timer.cancel();
}
GeneralDialog.Builder builder = new GeneralDialog.Builder(getAbility());
long hour = time / 60 / 60;
long mine = time / 60;
long sec = time % 60;
String leftTime = (hour < 10 ? "0" + hour : hour) + "时" +
(mine < 10 ? "0" + mine : mine) + "分" +
(sec < 10 ? "0" + sec : sec) + "秒";
builder.setTitle("消息提示")
.setContent("恭喜您挑战成功,用时" + leftTime)
.addButton("取消", GeneralButtonElement.TYPE_NORMAL, GeneralDialog::remove)
.addButton("确定", GeneralButtonElement.TYPE_ACCENT, GeneralDialog::remove)
// .addButton("ERROR", GeneralButtonElement.TYPE_ERROR, GeneralDialog::remove)
.create()
.show();
}
}
/**
* 检查是否结束
*/
private boolean checkFinish() {
boolean isSuccess = true;
for (int i = 0; i < pms.length - 1; i++) {
if (pms[i].getIndex() != i) {
isSuccess = false;
break;
}
}
return isSuccess;
}
private void initListContainer() {
listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
List<Integer> list = getData();
SampleItemProvider sampleItemProvider = new SampleItemProvider(list, this);
listContainer.setItemProvider(sampleItemProvider);
listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
if (isGaming) {
ToastUtils.show(getAbility(), "正在游戏中");
return;
}
hasPic = true;
initPicData(list.get(i));
});
listContainer.setBindStateChangedListener(new Component.BindStateChangedListener() {
@Override
public void onComponentBoundToWindow(Component component) {
// ListContainer初始化时数据统一在provider中创建,不直接调用这个接口;
// 建议在onComponentBoundToWindow监听或者其他事件监听中调用。
sampleItemProvider.notifyDataChanged();
}
@Override
public void onComponentUnboundFromWindow(Component component) {
}
});
}
private ArrayList<Integer> getData() {
ArrayList<Integer> list = new ArrayList<>();
list.add(ResourceTable.Media_demo01);
list.add(ResourceTable.Media_demo02);
list.add(ResourceTable.Media_demo03);
list.add(ResourceTable.Media_demo04);
list.add(ResourceTable.Media_demo05);
list.add(ResourceTable.Media_demo06);
return list;
}
/**
* 初始化每个格子
*/
private void initPicData() {
//定义数据能力帮助对象
DataAbilityHelper helper = DataAbilityHelper.creator(getContext());
//定义图片来源对象
ImageSource imageSource = null;
try {
//读取图片
FileDescriptor fd = helper.openFile(uri, "r");
imageSource = ImageSource.create(fd, null);
ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
int width = imageSource.getImageInfo().size.width / ROW_NUM;
int height = imageSource.getImageInfo().size.height / COL_NUM;
for (int i = 0; i < ROW_NUM; i++) {
for (int j = 0; j < COL_NUM; j++) {
int index = i * COL_NUM + j;
decodingOptions.desiredRegion = new Rect(j * width, i * height, width, height);
//创建位图
pixelMap = imageSource.createPixelmap(decodingOptions);
ImgSliceBean bean = new ImgSliceBean();
bean.setPixelMap(pixelMap);
bean.setIndex(i * COL_NUM + j);
pms[index] = bean;
if (i == ROW_NUM - 1 && j == COL_NUM - 1) {
bean.setBlank(true);
ivIndex[index].setVisibility(Component.HIDE);
ivImgs[index].setPixelMap(null);
} else {
//设置图片控件对应的位图
ivImgs[index].setPixelMap(pms[index].getPixelMap());
ivIndex[index].setText(pms[index].getIndex() + "");
ivIndex[index].setVisibility(Component.VISIBLE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (imageSource != null) {
imageSource.release();
}
}
}
/**
* 初始化每个格子
*/
private void initPicData(Integer id) {
//定义图片来源对象
ImageSource imageSource = null;
try {
Resource inputStream = getContext().getResourceManager().getResource(id);
imageSource = ImageSource.create(inputStream, null);
PixelMap pixelMap = imageSource.createPixelmap(null);
ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
int width = pixelMap.getImageInfo().size.width / ROW_NUM;
int height = pixelMap.getImageInfo().size.height / COL_NUM;
for (int i = 0; i < ROW_NUM; i++) {
for (int j = 0; j < COL_NUM; j++) {
int index = i * COL_NUM + j;
decodingOptions.desiredRegion = new Rect(j * width, i * height, width, height);
//创建位图
pixelMap = imageSource.createPixelmap(decodingOptions);
ImgSliceBean bean = new ImgSliceBean();
bean.setPixelMap(pixelMap);
bean.setIndex(i * COL_NUM + j);
pms[index] = bean;
if (i == ROW_NUM - 1 && j == COL_NUM - 1) {
bean.setBlank(true);
ivIndex[index].setVisibility(Component.HIDE);
ivImgs[index].setPixelMap(null);
} else {
//设置图片控件对应的位图
ivImgs[index].setPixelMap(pms[index].getPixelMap());
ivIndex[index].setText(pms[index].getIndex() + "");
ivIndex[index].setVisibility(Component.VISIBLE);
}
}
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (imageSource != null) {
imageSource.release();
}
}
}
}