从零开始开发Android版2048 (五) 撤销的实现

本篇的内容是,在前一篇的基础上加入了撤销的功能。撤销其实就是将当前的用户界面恢复到这次滑动值前的样子。我实现撤销的主要原理是,将每次滑动后界面上的格子和对应的数字记录下来,当然还有分数,把这些数据写入一个栈中,然后点击撤销操作的时候,将栈顶pop掉,读取下一个栈中的对象,并根据对象中存储的数据重新绘制界面。


下面是我用于存储每次界面情况的类,在这个类中保存了界面中主要的三个数据,空白格、数字格和当前的分数。

package com.example.t2048;

import java.util.ArrayList;
import java.util.List;

public class History {
	
	//对应主activity中的空格列表
	private List<Integer> spaceList;
	//对应主activity中的数字列表
	private NumberList numberList;
	//对应主activity中的当前分数
	private int score = 0;
	
	/**
	 * 构造方法
	 * @param sl  空格列表
	 * @param nl  数字列表
	 * @param s   当前分数
	 */
	History(List<Integer> sl, NumberList nl, int s) {
		spaceList = new ArrayList<Integer>(sl);
		numberList = new NumberList(new ArrayList<Integer>(nl.getStuffList()), new ArrayList<Integer>(nl.getNumberList()));
		this.score = s;
	}
	
	public List<Integer> getSpaceList(){
		return this.spaceList;
	}

	public NumberList getNumberList() {
		return this.numberList;
	}

	public int getScore() {
		return this.score;
	}
	
	/**
	 * 打印日志
	 */
	public void printLog(){
		System.out.println(this.spaceList.toString());
		this.numberList.printLog();
		System.out.println("score: "+this.score);
	}
}

然后,我在主Activity中声明了一个stack用于保存每次的History

	//保存历史记录,用于撤销操作
	Stack<History> historyStack = new Stack<History>();

在每次完成初始化以及每次有效的滑动之后,将当前界面的History压入stack中

	History history = new History(spaceList, numberList, score);
	historyStack.push(history);


执行撤销的操作,我写了如下方法,代码还是很简单的:

	/**
	 * 撤销操作,获取操作记录栈中最后的记录,并重绘界面
	 */
	public void goBack(){
		//至少应有一次有效滑动后才能撤销
		if(historyStack.size()>=2){
		    //将当前的界面记录在栈中弹出
			historyStack.pop();
			//取栈中第二个对象即为本次操作之前的界面的记录
			History history = historyStack.peek();
			
			numberList = history.getNumberList();
			spaceList = history.getSpaceList();
			score = history.getScore();	
			
			//调取方法,重绘界面
			drawViews(spaceList, numberList, score);
		}
	}
	
	/**
	 * 根据参数重绘界面
	 * @param spaceList      空白格列表
	 * @param numberList     数字格列表
	 * @param score          当前分数
	 */
	public void drawViews(List<Integer> spaceList, NumberList numberList, int score){
		scoreText.setText(score+"");	
		gridLayout.removeAllViews();			
		for(int i=0; i<16; i++){			
			View view = View.inflate(this, R.layout.item, null);
			ImageView image = (ImageView) view.findViewById(R.id.image);			
							
			if(numberList.contains(i))
				image.setBackgroundResource(icons[numberList.getNumberByIndex(i)]);				
			else
				image.setBackgroundResource(icons[0]);	
			gridLayout.addView(view);
		}
	}

 

完成以上代码后,将goback方法绑定到撤销按钮的onclicklistener中,就完成的撤销功能的实现。


        本篇的原理基本就是这样的,这样实现在代码上感觉比较好理解,但是在效率上有很大的问题,比如在用户的操作记录了很多之后,内存的占用率会比较高(没有实际检测过有多少),耗电肯定也会增加不少,我想这也是为什么有的版本的2048只提供几步撤销功能的原因之一吧。如果大家有什么更好的实现方法,欢迎留言或者私信,多交流促进共同进步哈。


最后,附上截至目前,所有的源码,如有问题希望大家批评指正

下载地址:http://download.csdn.net/detail/johnsonwce/7290697

从零开始开发Android版2048 (五) 撤销的实现,布布扣,bubuko.com

从零开始开发Android版2048 (五) 撤销的实现

上一篇:研究一下,手机边充电边用到底好不好


下一篇:C++中的RTTI机制