Android中贪吃蛇游戏的学习(三)

系统 1874 0

Android中贪吃蛇游戏的学习(三)

文章分类: 移动开发

视图VIew的类的Snake的,主要关注的学习的类。

Java代码
  1. package com.easyway.dev.android.snake;
  2. import java.util.ArrayList;
  3. import java.util.Random;
  4. import android.content.Context;
  5. import android.content.res.Resources;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.util.AttributeSet;
  10. import android.util.Log;
  11. import android.view.KeyEvent;
  12. import android.view.View;
  13. import android.widget.TextView;
  14. /**
  15. *View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。但它们之间有一些不同。每一个view
  16. *都有一个用于绘画的画布。这个画布可以用来进行任意扩展。
  17. *
  18. *一个项目的R.java文件是一个定义所有资源的索引文件。使用这个类就像使用一种速记方式来引用你项
  19. *目中包含的资源。这个有点特别的强大像对于Eclipse这类IDE的代码编译特性,因为它使你快速的,互动
  20. *式的定位你正在寻找的特定引用。
  21. *
  22. *到目前需要注意的重要事情是叫做”layout”的内部类和他的成员变量”main”,插件会通知你添加一个新
  23. *的XML布局文件,然后从新产生这个R.java文件,比如你添加了新的资源到你的项目,你将会看到R.java
  24. *也相应的改变了。放在你的项目目录的res/文件夹下。“res”是”resources”的缩写,它是存放所有非
  25. *代码资源的文件夹,包含象图片,本地化字符串和XML布局文件。
  26. *
  27. *
  28. *SnakeView:implementationofasimplegameofSnake
  29. *创建的view中一般要传入一个Context的实例,Context可以控制系统的调用,它提供了诸如资源解析
  30. *,访问数据库等。Activty类继承自Context类。
  31. *
  32. *视图也可以被嵌套,但和J2ME不同,我们可以将定制的视图和Android团队发布的Widgets一起使用。
  33. *在J2ME中,开发人员被迫选择GameCanvas和J2ME应用程序画布。这就意味着如果我们想要一个定制
  34. *的效果,就必须在GameCanvas上重新设计我们所有的widget。Android还不仅仅是这些,视图类型
  35. *也可以混合使用。Android还带了一个widget库,这个类库包括了滚动条,文本实体,进度条以及其
  36. *他很多控件。这些标准的widget可以被重载或被按着我们的习惯定制。
  37. *
  38. */
  39. public class SnakeView extends TileView{
  40. private static final StringTAG= "SnakeView" ;
  41. /**
  42. *Currentmodeofapplication:READYtorun,RUNNING,oryouhavealready
  43. *lost.staticfinalintsareusedinsteadofanenumforperformance
  44. *reasons.
  45. */
  46. private int mMode=READY;
  47. public static final int PAUSE= 0 ;
  48. public static final int READY= 1 ;
  49. public static final int RUNNING= 2 ;
  50. public static final int LOSE= 3 ;
  51. /**
  52. *设置方向
  53. *Currentdirectionthesnakeisheaded.
  54. */
  55. private int mDirection=NORTH;
  56. private int mNextDirection=NORTH;
  57. private static final int NORTH= 1 ;
  58. private static final int SOUTH= 2 ;
  59. private static final int EAST= 3 ;
  60. private static final int WEST= 4 ;
  61. /**
  62. *LabelsforthedrawablesthatwillbeloadedintotheTileViewclass
  63. */
  64. private static final int RED_STAR= 1 ;
  65. private static final int YELLOW_STAR= 2 ;
  66. private static final int GREEN_STAR= 3 ;
  67. /**
  68. *mScore:usedtotrackthenumberofapplescapturedmMoveDelay:numberof
  69. *millisecondsbetweensnakemovements.Thiswilldecreaseasapplesare
  70. *captured.
  71. */
  72. private long mScore= 0 ;
  73. private long mMoveDelay= 600 ;
  74. /**
  75. *mLastMove:trackstheabsolutetimewhenthesnakelastmoved,andisused
  76. *todetermineifamoveshouldbemadebasedonmMoveDelay.
  77. */
  78. private long mLastMove;
  79. /**
  80. *mStatusText:textshowstotheuserinsomerunstates
  81. */
  82. private TextViewmStatusText;
  83. /**
  84. *用于存储贪吃蛇中,苹果和蛇的点阵的坐标的信息的集合
  85. *mSnakeTrail:alistofCoordinatesthatmakeupthesnake'sbody
  86. *mAppleList:thesecretlocationofthejuicyapplesthesnakecraves.
  87. */
  88. private ArrayList<Coordinate>mSnakeTrail= new ArrayList<Coordinate>();
  89. private ArrayList<Coordinate>mAppleList= new ArrayList<Coordinate>();
  90. /**
  91. *为创建苹果坐标使用随机对象
  92. *Everyoneneedsalittlerandomnessintheirlife
  93. */
  94. private static final RandomRNG= new Random();
  95. /**
  96. *刷新界面处理器
  97. *Createasimplehandlerthatwecanusetocauseanimationtohappen.We
  98. *setourselvesasatargetandwecanusethesleep()
  99. *functiontocauseanupdate/invalidatetooccuratalaterdate.
  100. */
  101. private RefreshHandlermRedrawHandler= new RefreshHandler();
  102. /**
  103. *实现刷新的功能:
  104. *在J2ME中,刷新都是在canvas中通过调用线程结合repaint()来刷新,他们使线程不断去循环,
  105. *去调用canvas,笔者在android入门时也曾经想用J2ME的模式用在android中,结果报异常了,
  106. *为什么呢?很多人认为Dalvik虚拟机是一个Java虚拟机,因为Android的编程语言恰恰就是Java语言。
  107. *但是这种说法并不准确,因为Dalvik虚拟机并不是按照Java虚拟机的规范来实现的,两者并不兼容;
  108. *同时还要两个明显的不同:Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的
  109. *文件格式DEX(DalvikExecutable)。所以在以前JAVA里面能使用的模式,可能在android
  110. *里面用不起来。在自带的例子里面他是通过消息的机制来刷新的。而在android的消定义比较广泛,
  111. *比如,手机的暂停,启动,来电话、短信,键盘按下,弹起都是一个消息。总的来说,事件就是消息;
  112. *只要继承Handler类就可以对消息进行控制,或者处理,根据具体情况进行具体处理:
  113. *
  114. *@authorAdministrator
  115. *@date2010-5-24
  116. *@version1.0
  117. *@sinceJDK6.0
  118. */
  119. class RefreshHandler extends Handler{
  120. /**
  121. *响应消息
  122. */
  123. @Override
  124. public void handleMessage(Messagemsg){
  125. SnakeView. this .update();
  126. SnakeView. this .invalidate();
  127. }
  128. /**
  129. *向外提供人工的调用消息的接口
  130. *@paramdelayMillis
  131. */
  132. public void sleep( long delayMillis){
  133. //注销消息
  134. this .removeMessages( 0 );
  135. //添加消息
  136. sendMessageDelayed(obtainMessage( 0 ),delayMillis);
  137. }
  138. };
  139. /**
  140. *ConstructsaSnakeViewbasedoninflationfromXML
  141. *
  142. *@paramcontext
  143. *@paramattrs
  144. */
  145. public SnakeView(Contextcontext,AttributeSetattrs){
  146. super (context,attrs);
  147. initSnakeView();
  148. }
  149. public SnakeView(Contextcontext,AttributeSetattrs, int defStyle){
  150. super (context,attrs,defStyle);
  151. initSnakeView();
  152. }
  153. /**
  154. *初始化界面的
  155. */
  156. private void initSnakeView(){
  157. setFocusable( true );
  158. Resourcesr= this .getContext().getResources();
  159. resetTiles( 4 );
  160. loadTile(RED_STAR,r.getDrawable(R.drawable.redstar));
  161. loadTile(YELLOW_STAR,r.getDrawable(R.drawable.yellowstar));
  162. loadTile(GREEN_STAR,r.getDrawable(R.drawable.greenstar));
  163. }
  164. /**
  165. *初始化新的游戏
  166. */
  167. private void initNewGame(){
  168. mSnakeTrail.clear();
  169. mAppleList.clear();
  170. //Fornowwe'rejustgoingtoloadupashortdefaulteastboundsnake
  171. //that'sjustturnednorth
  172. //设置初始化蛇的位置
  173. mSnakeTrail.add( new Coordinate( 7 , 7 ));
  174. mSnakeTrail.add( new Coordinate( 6 , 7 ));
  175. mSnakeTrail.add( new Coordinate( 5 , 7 ));
  176. mSnakeTrail.add( new Coordinate( 4 , 7 ));
  177. mSnakeTrail.add( new Coordinate( 3 , 7 ));
  178. mSnakeTrail.add( new Coordinate( 2 , 7 ));
  179. mNextDirection=NORTH;
  180. //Twoapplestostartwith
  181. //设置苹果的位置
  182. addRandomApple();
  183. addRandomApple();
  184. //
  185. mMoveDelay= 600 ;
  186. //设置积分的
  187. mScore= 0 ;
  188. }
  189. /**
  190. *GivenaArrayListofcoordinates,weneedtoflattenthemintoanarrayof
  191. *intsbeforewecanstuffthemintoamapforflatteningandstorage.
  192. *
  193. *@paramcvec:aArrayListofCoordinateobjects
  194. *@return:asimplearraycontainingthex/yvaluesofthecoordinates
  195. *as[x1,y1,x2,y2,x3,y3...]
  196. */
  197. private int []coordArrayListToArray(ArrayList<Coordinate>cvec){
  198. int count=cvec.size();
  199. int []rawArray= new int [count* 2 ];
  200. for ( int index= 0 ;index<count;index++){
  201. Coordinatec=cvec.get(index);
  202. rawArray[ 2 *index]=c.x;
  203. rawArray[ 2 *index+ 1 ]=c.y;
  204. }
  205. return rawArray;
  206. }
  207. /**
  208. *Savegamestatesothattheuserdoesnotloseanything
  209. *ifthegameprocessiskilledwhileweareinthe
  210. *background.
  211. *
  212. *@returnaBundlewiththisview'sstate
  213. */
  214. public BundlesaveState(){
  215. Bundlemap= new Bundle();
  216. map.putIntArray( "mAppleList" ,coordArrayListToArray(mAppleList));
  217. map.putInt( "mDirection" ,Integer.valueOf(mDirection));
  218. map.putInt( "mNextDirection" ,Integer.valueOf(mNextDirection));
  219. map.putLong( "mMoveDelay" ,Long.valueOf(mMoveDelay));
  220. map.putLong( "mScore" ,Long.valueOf(mScore));
  221. map.putIntArray( "mSnakeTrail" ,coordArrayListToArray(mSnakeTrail));
  222. return map;
  223. }
  224. /**
  225. *Givenaflattenedarrayofordinatepairs,wereconstitutethemintoa
  226. *ArrayListofCoordinateobjects
  227. *
  228. *@paramrawArray:[x1,y1,x2,y2,...]
  229. *@returnaArrayListofCoordinates
  230. */
  231. private ArrayList<Coordinate>coordArrayToArrayList( int []rawArray){
  232. ArrayList<Coordinate>coordArrayList= new ArrayList<Coordinate>();
  233. int coordCount=rawArray.length;
  234. for ( int index= 0 ;index<coordCount;index+= 2 ){
  235. Coordinatec= new Coordinate(rawArray[index],rawArray[index+ 1 ]);
  236. coordArrayList.add(c);
  237. }
  238. return coordArrayList;
  239. }
  240. /**
  241. *Restoregamestateifourprocessisbeingrelaunched
  242. *
  243. *@paramicicleaBundlecontainingthegamestate
  244. */
  245. public void restoreState(Bundleicicle){
  246. setMode(PAUSE);
  247. //从资源中获取ArrayList
  248. mAppleList=coordArrayToArrayList(icicle.getIntArray( "mAppleList" ));
  249. mDirection=icicle.getInt( "mDirection" );
  250. mNextDirection=icicle.getInt( "mNextDirection" );
  251. mMoveDelay=icicle.getLong( "mMoveDelay" );
  252. mScore=icicle.getLong( "mScore" );
  253. mSnakeTrail=coordArrayToArrayList(icicle.getIntArray( "mSnakeTrail" ));
  254. }
  255. /**
  256. *重点的控制代码
  257. *
  258. *实现键盘事件:键盘主要起操作作用,在任何的手机游戏中键盘都是起重要的用,要本游戏中,
  259. *他就是起控制蛇的行走方向:现在我们分析他的代码:
  260. *就是通过判断那个键按下,然后再给要走的方向(mDirection)赋值。
  261. *
  262. *handleskeyeventsinthegame.Updatethedirectionoursnakeistraveling
  263. *basedontheDPAD.Ignoreeventsthatwouldcausethesnaketoimmediately
  264. *turnbackonitself.
  265. *
  266. *(non-Javadoc)
  267. *
  268. *@seeandroid.view.View#onKeyDown(int,android.os.KeyEvent)
  269. */
  270. @Override
  271. public boolean onKeyDown( int keyCode,KeyEventmsg){
  272. if (keyCode==KeyEvent.KEYCODE_DPAD_UP){
  273. if (mMode==READY|mMode==LOSE){
  274. /*
  275. *Atthebeginningofthegame,ortheendofapreviousone,
  276. *weshouldstartanewgame.
  277. */
  278. initNewGame();
  279. setMode(RUNNING);
  280. update();
  281. return ( true );
  282. }
  283. if (mMode==PAUSE){
  284. /*
  285. *Ifthegameismerelypaused,weshouldjustcontinuewhere
  286. *weleftoff.
  287. */
  288. setMode(RUNNING);
  289. update();
  290. return ( true );
  291. }
  292. if (mDirection!=SOUTH){
  293. mNextDirection=NORTH;
  294. }
  295. return ( true );
  296. }
  297. if (keyCode==KeyEvent.KEYCODE_DPAD_DOWN){
  298. if (mDirection!=NORTH){
  299. mNextDirection=SOUTH;
  300. }
  301. return ( true );
  302. }
  303. if (keyCode==KeyEvent.KEYCODE_DPAD_LEFT){
  304. if (mDirection!=EAST){
  305. mNextDirection=WEST;
  306. }
  307. return ( true );
  308. }
  309. if (keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){
  310. if (mDirection!=WEST){
  311. mNextDirection=EAST;
  312. }
  313. return ( true );
  314. }
  315. return super .onKeyDown(keyCode,msg);
  316. }
  317. /**
  318. *SetstheTextViewthatwillbeusedtogiveinformation(suchas"Game
  319. *Over"totheuser.
  320. *
  321. *@paramnewView
  322. */
  323. public void setTextView(TextViewnewView){
  324. mStatusText=newView;
  325. }
  326. /**
  327. *Updatesthecurrentmodeoftheapplication(RUNNINGorPAUSEDorthelike)
  328. *aswellassetsthevisibilityoftextviewfornotification
  329. *
  330. *@paramnewMode
  331. */
  332. public void setMode( int newMode){
  333. int oldMode=mMode;
  334. mMode=newMode;
  335. if (newMode==RUNNING&oldMode!=RUNNING){
  336. mStatusText.setVisibility(View.INVISIBLE);
  337. update();
  338. return ;
  339. }
  340. Resourcesres=getContext().getResources();
  341. CharSequencestr= "" ;
  342. if (newMode==PAUSE){
  343. str=res.getText(R.string.mode_pause);
  344. }
  345. if (newMode==READY){
  346. str=res.getText(R.string.mode_ready);
  347. }
  348. if (newMode==LOSE){
  349. str=res.getString(R.string.mode_lose_prefix)+mScore
  350. +res.getString(R.string.mode_lose_suffix);
  351. }
  352. mStatusText.setText(str);
  353. mStatusText.setVisibility(View.VISIBLE);
  354. }
  355. /**
  356. *
  357. *生成苹果位置的代码:
  358. *苹果的位置就是更简单了,他是随机生成的,而且必须在现在蛇的位置相对远距离。
  359. *
  360. *Selectsarandomlocationwithinthegardenthatisnotcurrentlycovered
  361. *bythesnake.Currently_could_gointoaninfiniteloopifthesnake
  362. *currentlyfillsthegarden,butwe'llleavediscoveryofthisprizetoa
  363. *trulyexcellentsnake-player.
  364. *
  365. */
  366. private void addRandomApple(){
  367. CoordinatenewCoord= null ;
  368. boolean found= false ;
  369. while (!found){
  370. //随机生成新的X,Y位置
  371. //Chooseanewlocationforourapple
  372. int newX= 1 +RNG.nextInt(mXTileCount- 2 );
  373. int newY= 1 +RNG.nextInt(mYTileCount- 2 );
  374. newCoord= new Coordinate(newX,newY);
  375. //Makesureit'snotalreadyunderthesnake
  376. boolean collision= false ;
  377. int snakelength=mSnakeTrail.size();
  378. for ( int index= 0 ;index<snakelength;index++){
  379. //检查一下存放的位置是否合理
  380. if (mSnakeTrail.get(index).equals(newCoord)){
  381. collision= true ;
  382. }
  383. }
  384. //ifwe'rehereandthere'sbeennocollision,thenwehave
  385. //agoodlocationforanapple.Otherwise,we'llcircleback
  386. //andtryagain
  387. found=!collision;
  388. }
  389. if (newCoord== null ){
  390. Log.e(TAG, "SomehowendedupwithanullnewCoord!" );
  391. }
  392. //添加苹果的列表中的
  393. mAppleList.add(newCoord);
  394. }
  395. /**
  396. *Handlesthebasicupdateloop,checkingtoseeifweareintherunning
  397. *state,determiningifamoveshouldbemade,updatingthesnake'slocation.
  398. */
  399. public void update(){
  400. if (mMode==RUNNING){
  401. long now=System.currentTimeMillis();
  402. if (now-mLastMove>mMoveDelay){
  403. clearTiles();
  404. updateWalls();
  405. updateSnake();
  406. updateApples();
  407. mLastMove=now;
  408. }
  409. mRedrawHandler.sleep(mMoveDelay);
  410. }
  411. }
  412. /**
  413. *调用以上的方法以循环的方式位置数组赋值以及图片的索引。
  414. *
  415. *Drawssomewalls.
  416. *
  417. */
  418. private void updateWalls(){
  419. for ( int x= 0 ;x<mXTileCount;x++){
  420. setTile(GREEN_STAR,x, 0 ); //设置顶部的界限的位置
  421. setTile(GREEN_STAR,x,mYTileCount- 1 ); //设置底部界限的位置
  422. }
  423. for ( int y= 1 ;y<mYTileCount- 1 ;y++){
  424. setTile(GREEN_STAR, 0 ,y); //设置顶部的界限的位置
  425. setTile(GREEN_STAR,mXTileCount- 1 ,y); //设置底部界限的位置
  426. }
  427. }
  428. /**
  429. *Drawssomeapples.
  430. *
  431. */
  432. private void updateApples(){
  433. for (Coordinatec:mAppleList){
  434. setTile(YELLOW_STAR,c.x,c.y);
  435. }
  436. }
  437. /**
  438. *设置当前蛇的方向位置:
  439. *从以上的键盘代码我们可以看得出,程序中是通过触发来改变坐标(+1,-1)的方式来改蛇头的方向,
  440. *可见坐标在游戏编程中的作用,这个也是根据手机的屏幕是点阵的方式来显示,所以坐标就是一个
  441. *定位器。在这里大家可能还有一个疑问。就是就这个蛇什么能够以“7”字形来移动行走,其实我们
  442. *稍微仔细观察一下就知道了,在这里面,他们也是通过坐标的传递来实现的,只要把头部的坐标点
  443. *依次赋给下一个点,后面的每一个点都走过了头部所走过的点,而蛇的头部就是负责去获取坐标,整
  444. *个蛇的行走起来就很自然和连贯。坐标的方向变换又是通过判断那个方向按键的按下来改变的,这
  445. *样一来,键盘的作用就发挥出来了。蛇吃苹果又是怎样去实现?上面我所说到的坐标就起了作用。在蛇
  446. *所经过的每一个坐标,他们都要在苹果所在的(ArrayList<Coordinate>mAppleList=new
  447. *ArrayList<Coordinate>())坐标集里面集依次判断,若是坐标相同,那个这个苹果就被蛇吃了。
  448. *
  449. *Figureoutwhichwaythesnakeisgoing,seeifhe'srunintoanything(the
  450. *walls,himself,oranapple).Ifhe'snotgoingtodie,wethenaddtothe
  451. *frontandsubtractfromtherearinordertosimulatemotion.Ifwewantto
  452. *growhim,wedon'tsubtractfromtherear.
  453. *
  454. */
  455. private void updateSnake(){
  456. boolean growSnake= false ;
  457. //grabthesnakebythehead
  458. //获取蛇的头部
  459. Coordinatehead=mSnakeTrail.get( 0 );
  460. //创建一个新的蛇的头部应该的位置
  461. CoordinatenewHead= new Coordinate( 1 , 1 );
  462. //根据当前的为方向设置坐标的信息
  463. mDirection=mNextDirection;
  464. switch (mDirection){
  465. case EAST:{
  466. newHead= new Coordinate(head.x+ 1 ,head.y);
  467. break ;
  468. }
  469. case WEST:{
  470. newHead= new Coordinate(head.x- 1 ,head.y);
  471. break ;
  472. }
  473. case NORTH:{
  474. newHead= new Coordinate(head.x,head.y- 1 );
  475. break ;
  476. }
  477. case SOUTH:{
  478. newHead= new Coordinate(head.x,head.y+ 1 );
  479. break ;
  480. }
  481. }
  482. //Collisiondetection
  483. //Fornowwehavea1-squarewallaroundtheentirearena
  484. if ((newHead.x< 1 )||(newHead.y< 1 )||(newHead.x>mXTileCount- 2 )
  485. ||(newHead.y>mYTileCount- 2 )){
  486. setMode(LOSE);
  487. return ;
  488. }
  489. //Lookforcollisionswithitself
  490. int snakelength=mSnakeTrail.size();
  491. for ( int snakeindex= 0 ;snakeindex<snakelength;snakeindex++){
  492. Coordinatec=mSnakeTrail.get(snakeindex);
  493. if (c.equals(newHead)){
  494. setMode(LOSE);
  495. return ;
  496. }
  497. }
  498. //Lookforapples
  499. //查找苹果设置苹果新的位置的信息
  500. int applecount=mAppleList.size();
  501. for ( int appleindex= 0 ;appleindex<applecount;appleindex++){
  502. Coordinatec=mAppleList.get(appleindex);
  503. if (c.equals(newHead)){
  504. mAppleList.remove(c);
  505. addRandomApple();
  506. mScore++;
  507. //设置的移动的速度
  508. mMoveDelay*= 0.9 ;
  509. growSnake= true ;
  510. }
  511. }
  512. //将蛇头的位置信息放在第一个的对象中方取值
  513. //pushanewheadontotheArrayListandpulloffthetail
  514. mSnakeTrail.add( 0 ,newHead);
  515. //exceptifwewantthesnaketogrow
  516. if (!growSnake){
  517. mSnakeTrail.remove(mSnakeTrail.size()- 1 );
  518. }
  519. int index= 0 ;
  520. for (Coordinatec:mSnakeTrail){
  521. if (index== 0 ){
  522. setTile(YELLOW_STAR,c.x,c.y);
  523. } else {
  524. setTile(RED_STAR,c.x,c.y);
  525. }
  526. index++;
  527. }
  528. }
  529. /**
  530. *用于存储每一个位点的x,y坐标信息
  531. *Simpleclasscontainingtwointegervaluesandacomparisonfunction.
  532. *There'sprobablysomethingIshoulduseinstead,butthiswasquickand
  533. *easytobuild.
  534. *
  535. */
  536. private class Coordinate{
  537. public int x;
  538. public int y;
  539. public Coordinate( int newX, int newY){
  540. x=newX;
  541. y=newY;
  542. }
  543. public boolean equals(Coordinateother){
  544. if (x==other.x&&y==other.y){
  545. return true ;
  546. }
  547. return false ;
  548. }
  549. @Override
  550. public StringtoString(){
  551. return "Coordinate:[" +x+ "," +y+ "]" ;
  552. }
  553. }
  554. }

Android中贪吃蛇游戏的学习(三)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论