我整理了一下,顺便加了一点屏幕切换的代码,网速太不给力,好几次都坑了

直接上代码吧,稍后总结,简单粗暴,详情看题目
主程序:

package com.andy.andy.myapplication;import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;public class MainActivity extends ActionBarActivity {Button button;RelativeLayout layout;WuziqiPannel wuziqiPannel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);layout = (RelativeLayout) findViewById(R.id.layout);button = (Button) findViewById(R.id.button);wuziqiPannel = (WuziqiPannel) findViewById(R.id.wuziqi);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {wuziqiPannel.start();}});//  int orientationPortrait = Configuration.ORIENTATION_PORTRAIT;//1  竖着的// layout.addView(button, lp);}/*** 优点:我们可以随时监听屏幕旋转变化,并对应做出相应的操作;* 缺点:它只能一次旋转90度,如果一下子旋转180度,onConfigurationChanged函数不会被调用。** @param newConfig*/@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);Log.e("lc---", "onConfigurationChanged");// int isVer = getResources().getConfiguration().orientation;if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {// lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, R.id.button);lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);// button.setLayoutParams(new RelativeLayout.LayoutParams());} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {//  lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.button);
//            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.button);lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//  button.setLayoutParams(lp);//好用}button.setLayoutParams(lp);}
}

自定义控件WuziqiPannel.java

package com.andy.andy.myapplication;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;import java.util.ArrayList;
import java.util.List;/*** Created by andy on 2016/6/12.*/
public class WuziqiPannel extends View {private int mPanelWidth;private float mLineHeight;//行高  为何是float?精度,屏幕的宽 通常计算出来通常不是整数private int MAX_LINE = 10;//尺寸相关,在哪里初始化呢  onsizechange()private Paint mPaint = new Paint();private Bitmap mWhitePiece;private Bitmap mBlackPiece;private float ratioPieceOfLineHeight = 3 * 1.0f / 4;//白起先手 还是轮到白起?private boolean mIsWhite = true;
//    private List<Point> mWhiteArray = new ArrayList<Point>();
//    private List<Point> mBlackArray = new ArrayList<Point>();private ArrayList<Point> mWhiteArray = new ArrayList<Point>();private ArrayList<Point> mBlackArray = new ArrayList<Point>();private boolean mIsGameOver;private boolean mIsWhiteWinner;private  int MAX_COUNT_IN_LINE = 5;public WuziqiPannel(Context context, AttributeSet attrs) {super(context, attrs);setBackgroundColor(0x44ff0000);init();}private void init() {mPaint.setColor(0x88000000);mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setStyle(Paint.Style.STROKE);mWhitePiece = BitmapFactory.decodeResource(getResources(), R.drawable.bai);//从 资源文件中 取图片mBlackPiece = BitmapFactory.decodeResource(getResources(), R.drawable.hei);}/*首先 view 的测量*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSize = MeasureSpec.getSize(widthMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int width = Math.min(widthSize, heightSize);/*这个判断主要解决 自定义view 嵌套在scrollview 中时,获取不到宽高,或者宽高为0 的情况的处理*/if (widthMode == MeasureSpec.UNSPECIFIED) {width = heightSize;} else if (heightMode == MeasureSpec.UNSPECIFIED) {width = widthSize;}setMeasuredDimension(width, width);//一个正方形的框}/*** 和尺寸相关的 初始化都写在这个地方** @param w* @param h* @param oldw* @param oldh*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mPanelWidth = w;mLineHeight = mPanelWidth * 1.0f / MAX_LINE;int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece, pieceWidth, pieceWidth, false);mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece, pieceWidth, pieceWidth, false);}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mIsGameOver){return false;}int action = event.getAction();if (action == MotionEvent.ACTION_DOWN) {return true;}if (action == MotionEvent.ACTION_UP) {int x = (int) event.getX();int y = (int) event.getY();// Point p = new Point(x,y);// 一个合法的区域Point p = getValidPoint(x, y);if (mWhiteArray.contains(p) || mBlackArray.contains(p)) {return false;///?????---------o 不处理这个事件,不添加,不显示子}if (mIsWhite) {mWhiteArray.add(p);} else {mBlackArray.add(p);}invalidate();mIsWhite = !mIsWhite;//  return true;//ACTION_DOWN一定要标明自己的态度,自己对这个事件感兴趣}return true;}private Point getValidPoint(int x, int y) {return new Point((int) (x / mLineHeight), (int) (y / mLineHeight));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBoard(canvas);drawPieces(canvas);checkGameOver();}private void checkGameOver() {boolean whiteWin = checkFiveInLine(mWhiteArray);boolean blackWin = checkFiveInLine(mBlackArray);if (whiteWin || blackWin){mIsGameOver = true;mIsWhiteWinner = whiteWin;String text  = mIsWhiteWinner?"白起胜利":"黑棋胜利";Toast.makeText(getContext(),text,Toast.LENGTH_SHORT).show();}}private boolean checkFiveInLine(List<Point> points) {for (Point p :points){int x =p.x;int y = p.y;boolean win =  checkHorizontal(x,y,points);if (win){return true;}win  =checkVertical(x,y,points);if (win){return true;}win  =checkLeftDiagonal(x,y,points);if (win){return true;}win  =checkRightDiagonal(x,y,points);if (win){return true;}}return false;}/*** 判断 横向 是否 5 个相连  每次只对当前落子的位置进行 判断,还不是很耗时* @param x* @param y* @param points* @return*/private boolean checkHorizontal(int x, int y, List<Point> points) {int count = 1;for (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x-i,y))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;for (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x+i,y))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;return false;}private boolean checkVertical(int x, int y, List<Point> points) {int count = 1;//shang xiafor (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x,y-i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;for (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x,y+i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;return false;}private boolean checkLeftDiagonal(int x, int y, List<Point> points) {int count = 1;//shang xiafor (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x-i,y-i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;for (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x+i,y+i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;return false;}private boolean checkRightDiagonal(int x, int y, List<Point> points) {int count = 1;//shang xiafor (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x-i,y+i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;for (int i = 1;i <MAX_COUNT_IN_LINE ;i++){if (points.contains(new Point(x+i,y-i))){count++;}else {break;}}if (count ==MAX_COUNT_IN_LINE)return true;return false;}/*** 绘制棋子   测试 要减2 不知道是 什么鬼 gety  和 getRawy.** @param canvas*/private void drawPieces(Canvas canvas) {for (int i = 0, n = mWhiteArray.size(); i < n; i++) {Point whitePoint = mWhiteArray.get(i);Log.e("lc---",(whitePoint.y)+"");canvas.drawBitmap(mWhitePiece,(whitePoint.x + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight,(whitePoint.y  + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight, null); TODO: 2016/6/13  -2}for (int i = 0, n = mBlackArray.size(); i < n; i++) {Point blackPoint = mBlackArray.get(i);canvas.drawBitmap(mBlackPiece, (blackPoint.x + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight, (blackPoint.y  + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight, null);}}private void drawBoard(Canvas canvas) {//上下各有 半个的 lineheightint w = mPanelWidth;float lineHeight = mLineHeight;for (int i = 0; i < MAX_LINE; i++) {int startX = (int) lineHeight / 2;int endX = (int) (w - lineHeight / 2);int y = (int) ((0.5 + i) * lineHeight);canvas.drawLine(startX, y, endX, y, mPaint);//横线canvas.drawLine(y, startX, y, endX, mPaint);}}private static final String INSTANCE ="instance";private static final String INSTANCE_GAME_OVER ="instance_game_over";private static final String INSTANCE_WHITE_ARRAY ="instance_white_array";private static final String INSTANCE_BLACK_ARRAY="instance_black_array";@Overrideprotected Parcelable onSaveInstanceState() {Bundle bundle = new Bundle();bundle.putParcelable(INSTANCE,super.onSaveInstanceState());bundle.putBoolean(INSTANCE_GAME_OVER, mIsGameOver);bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, mWhiteArray);bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);return bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {if (state instanceof Bundle){Bundle bundle = (Bundle) state;mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);super.onRestoreInstanceState(bundle.getParcelable(INSTANCE)); TODO: 2016/6/15 和 下边这句 super 不重复吗return;}super.onRestoreInstanceState(state);//---}public void start(){mWhiteArray.clear();mBlackArray.clear();mIsGameOver = false;mIsWhiteWinner = false;invalidate();}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.andy.andy.myapplication" ><application
        android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme" ><activity
            android:name=".MainActivity"android:configChanges="keyboardHidden|orientation|screenSize"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

资源文件,drawable-hdpi


activity_main.xml 布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/layout"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/backg"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"><!--加上id才能保存状态信息--><com.andy.andy.myapplication.WuziqiPannel
        android:id="@+id/wuziqi"android:layout_width="match_parent"android:layout_height="match_parent"android:text="Hello World!" /><Button
        android:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="重开一局" />
</RelativeLayout>

好了没有什么遗漏了.

总结下 自定义view的 步骤 思路:

  1. 编写xml布局
  2. 初始化测量 onMeasure 方法, onSizeChange()方法–初始化尺寸,
  3. 初始化 棋盘
  4. onTouch时间处理 down 的时候返回ture,表示我对这个触摸事件感兴趣,我要处理
  5. 绘制旗子 –
  6. 逻辑判断.三点 1 gameover 和 一个位置不可重复放子.2 在某个范围内 都下在 网格中心点上
  7. view的存储and恢复
  8. 再来一局
  9. 其他 屏幕尺寸改变需要注意的事项

备注: 自定义view的思路完全是自上而下的

五子棋 手打稍加改变自慕课网hyman相关推荐

  1. html5 css js前端开发五子棋UI篇--基于慕课网五子棋视频教程的随笔

    第一次写笔记,不知道带有别的网站是否违规,为了尊重别人果实,这次笔记就是基于慕课网五子棋教程,大家有兴趣可以去看一下.我自己增加了开始,暂停,继续,重新开始的按钮,由于是新手,最大目的在于实现功能,其 ...

  2. 五子棋的实现“慕课网五子连珠的笔记”

    慕课网的视频 首先创建了一个类,这个类继承了View,去实现这个类的构造方法,实现其两个参数的构造方法,老师建议自己写的过程中对这些构造方法都进行实现. 在布局文件中对这个类进行使用,注意是包名.宽高 ...

  3. 慕课网 饿了么 vue2.0 项目

    饿了么 vue 项目总结 项目效果预览 ele效果预览 项目源码地址 ele源码 跟着慕课网黄轶老师 敲饿了么 vue 项目 作者项目源代码地址 项目完成之后 npm run build 这本来是写在 ...

  4. 慕课网 前端JS面试技巧 笔记

    前言 关于面试 前端水平的三个层次 基层工程师-基础知识 高级工程师-项目经验 架构师- 解决方案 几个面试题 题目很多,做具有代表的题目,举一反三 js 中使用 typeof 能得到哪些类型 (== ...

  5. CSS浮动--慕课网

    1.div简介 div的溢出处理 owerflow属性 边框属性 2.盒子模型 盒子模型主要是用来改变外间距和内间距的 ,像 div table body 所有块状显示的即以矩形区域显示的都适合于盒子 ...

  6. JavaScript进阶篇(慕课网)

    <h5>第1章 系好安全带,准备启航 </h5> <b>1.1让你认识JS</b> 1.1.1 JavaScript能做什么? 增强页面动态效果(如:下 ...

  7. 【恢复】慕课网《网页布局基础》学习笔记

    好久之前,最初入坑前端时的学习笔记.那时候「慕课网」的几个路径还是免费的,也有好几个跟网页布局有关的课程,其中有一个叫<网页布局基础>讲得很棒,那时候刚好喜欢上 markdown 写作,于 ...

  8. 慕课网“小慕听书“ireader项目

    此项目源于慕课网 (https://www.imooc.com/) 功能: 可切换男音,女音,河南男方言三种音色以不同的语速,音量朗读文本内容 效果图: 思维导图: 基本代码: 绘制窗口大小,标题等( ...

  9. 仿慕课网视频播放界面协调布局

    近日使用慕课网APP的时候,发现一个页面效果感觉很有意思(正常情况下页面可以滑动,但是当页面中播放视频的时候,只有 下面可以滑动),所以仿照这做了一个,效果图如下: 主要是通过改变AppBarLayo ...

最新文章

  1. Android开发RSS阅读器
  2. 【Matlab 图像】图像基础操作
  3. 高仿真的类-业务逻辑注入接口
  4. 中控ecs700 mysql_浙大中控ECS700工程指导手册.pdf
  5. mongoose 笔记
  6. [译]时间自动机:语义,算法和工具
  7. 张家口以太坊智能合约开发实战pdf_以太坊2.0:实现可扩展性之路漫长而曲折
  8. 如何从Swift调用Objective-C代码?
  9. linux 777权限_认识Linux之Linux命令-用户、权限管理(8)
  10. 在VBA中使用正则表达式
  11. java apktool if_apktool反编译详细使用教程
  12. 教育部双一流计算机科学与技术,双一流大学及学科详情.pdf
  13. [na]win7系统安装在t450s
  14. MySQL第一节课总结
  15. c语言pow函数原型_C语言pow函数
  16. 课堂教学实践研究之人教版九年级上册“阅读与思考”《旋转对称》
  17. 华硕天选 3 和 联想拯救者 Y9000P 2022 款 哪个好
  18. 【基金学习】学习基本概念
  19. HC-SR04超声波测距模块的高精度使用方法
  20. Python正则匹配的应用——替换括号及括号内字符、文本分句

热门文章

  1. ps抠图基础篇:最常用的四种抠图方法
  2. Typescript详解
  3. 金多多配资盘面预测收益大于风险
  4. 业界红包玩法与技术方案总结
  5. js中的经典题Foo.getName
  6. Arduino基础2
  7. Android之微信界面设计
  8. oracle linux 退格,oracle database for linux 不能使用退格键
  9. 微型计算机原理顺序程序设计,微机原理实验,顺序实验.docx
  10. 关于 QMessageBox定制大小重写showEvent失败的 解决方法