突然想要在android上写一个消消乐的代码,在此之前没有系统地学过java的面向对象,也没有任何android相关知识,不过还是会一点C 。8月初开始搭建环境,在这上面花了相当多的时间,然后看了一些视频和电子书,对android有了一个大概的了解,感觉差不多了的时候就开始写了。

疯狂地查阅各种资料,反反复复了好几天后,也算是写出了个成品。原计划有很多地方还是可以继续写下去的,比如UI设计,比如动画特效,时间设计,关卡设计,以及与数据库的连接,如果可以的话还能写个联网功能,当然因为写到后期内心感到格外的疲倦,所以以上内容全部被砍掉了。

所以最后的成果就只有这样了……因为完全没有设计过所以非常难看,功能也只有消方块而已,图片还是从之前写的连连看里搬过来的。反正就算一个小的demo好了。

布局

一开始设计的布局是xml里的,但是后来想了想有64个按钮这样复制下去实在是太不好了,所以就把按钮那一部分用代码布局了。

private void initBtn(int i,int j)
  {
		btn[8*i j].setBackgroundDrawable
		(this.getResources().getDrawable(getStyle()));
		point p = new point(i,j,btn[8*i j],id);
		btn[8*i j].setTag(p);
		map[i][j] = num;
  }
 
//……
    LinearLayout vlayout = (LinearLayout)findViewById(R.id.vlayout);
    TableLayout tlayout = new TableLayout(this);
    TableRow row[] = new TableRow[8];
    for(int i=0;i<8;i  ){
    	row[i] = new TableRow(this);
    	row[i].setGravity(Gravity.CENTER);
    	for(int j=0;j<8;j  ){
    		btn[8*i j] = new ImageButton(this);
    		btn[8*i j].setLayoutParams(new TableRow.LayoutParams(38,38));
    		initBtn(i,j);
    		btn[8*i j].setOnClickListener(listener);
    		row[i].addView(btn[8*i j]);
    	}
    	tlayout.addView(row[i]);
    }
//……

其中getStyle()函数返回了按钮的样式id,该id是随机生成的。

point p存储了关于按钮的信息,它在按钮点击事件中会被使用。

android中的按钮有三种状态:点击态、普通态、焦点态。最后一个的意思是用户按方向键盘(或类似功能键)来控制哪个按钮处于焦点,这样就可以不通过鼠标对按钮进行操作。当然在这里并没有用到这个状态,只用到了前面两种,但是因为已经有现成图片了,就把三种状态都写入了btn?.xml(放在drawable文件夹下),使用的时候直接引用这个xml文件就可以了。

btn1.xml:

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
 
  <item android:drawable="@drawable/a1_2" android:state_pressed="true"/> 
  <item android:drawable="@drawable/a1" android:state_focused="false" android:state_pressed="false"/> 
  <item android:drawable="@drawable/a1_1" android:state_focused="true"/> 
  <item android:drawable="@drawable/a1" android:state_focused="false"/> 
 
</selector>

判断是否可消去

在点击事件中,用两个变量记录先后点击的按钮信息,这两个变量是滚动使用的,也就是说,第一次点击存入变量1,第二次点击存入变量2,第三次点击存入变量1,第四次点击存入变量2……额外有一个布尔变来控制信息存入哪个变量。

每次点击后,都计算先后两次点击的按钮是否相邻。如果相邻,那么交换它们的位置。

我们用二维数组mark来记录每个方块是否可以消去,初始化为0。交换后,先一行行地扫描一遍,检查是否有相连的三个以上图案相同的按钮,如果有的话,把它们都做上标记。然后再一列列扫描一遍,同样检查是否有相连的三个以上图案相同的按钮。总体复杂度为O(2*n^2)

当然可以有更快的算法,但是在这个代码里,我们对计算的速度没有要求,甚至希望它慢一些(因为动画效果需要在这里停顿一下),所以就没有必要进行优化了。

那么mark里存储些什么呢?一开始我把mark设计为布尔量,可消去的设为true。后来写到消去后更新按钮后,我突然想到mark里不仅仅可以记录是否可消去,还可以记录消去后应该更新为什么。

我们知道,消去一行按钮后,上面的按钮会掉下来补充空位,也就是说消去的这一行会被上面一行取代。所以我们把这些按钮的mark赋值为1。

同样,消去一列n个按钮后,每个按钮会被它上面第n个按钮取代,所以我们把这些按钮的mark赋值为n。
这样,在更新的时候,我们只需要遍历二维数组mark,根据它对应的值,来采取相应的操作就可以了。

在这里,要注意顺序性的问题,首先,在赋值mark的时候,应该先扫描横行,再扫描竖列,因为可能会出现十字架或T字型的消去,这里横纵有重叠,而更新的时候以纵为准,所以后扫描纵列来覆盖横行的值。

另外一个要注意的顺序,就是在更新的时候,一定要从上往下扫描。如果从下往上扫描的话,下面图案的更新可能会破坏到上面的图,那么,上面原来存在的可以被消去的方块就已经被破坏了,但是mark还记录着消去方块的索引,这样就会引起错的消去。反之,上面图案的消去是不会破坏下面的图案的。

判断地图是否还存在解

每一轮消去后,我们都需要判断地图上是否还存在解,如果不存在,就要进行更新

因为仅仅是判断存在性,算法略有变化。

我们需要考虑到所有的交换情况,以及它们能否产生可行解,一旦找到一个,我们就可以返回true。所以外循环包含两个,一个扫描横向相邻的所有方块,一个扫描纵向相邻的所有方块。

对于特定的两个方块,我们先交换它们,然后对于两个方块,都计算它们的十字架区域是否存在可行解,之后再把它们交换回来:

 

(十字架区域)
总体的最坏时间复杂度是2*(n^2)*2*8。

多线程

在主线程里,按理来说应该有消去 — 更新这样的画面,但是我发现android是直接把所有东西都计算了出来,然后再去显示UI的,而不是边计算边显示,所以我之前设置的那些一步步更新画面的代码一点儿用也没有,然后我想了想估计是要用多线程来写,在此之前我没有写过多线程的代码,所以花了一天时间看了多线程并把这部分修正了。

大概的想法是这样的:每次点击了两个相邻按钮后,先交换两个按钮,然后调用线程的start()方法。

在线程重写的run()方法里,先计算是否存在解(find函数),如果可以消去,每隔0.03s发送一个消息,通知主线程,主线程设置按钮的alpha值减小(增加透明度),反复10次,这样就做出了按钮慢慢消失的效果。

之后,再停顿0.1s,向主线程发送一个消息,主线程开始进行更新按钮操作。更新之后,因为掉落下来的按钮还可能组成新的可消去的部分,所以继续调用线程的start方法,直到不存在可消去的按钮。

如果不存在解,那么,先判断这是因为用户点击的两个按钮无法产生解,还是之前消去后掉落下来的按钮不会产生解。我们用flag来记录这一状态。如果是前者,先停顿0.3s,再把两个按钮的位置交换回来;如果是后者,说明已经消去所有按钮,这时我们检查是否还存在可行解,如果不存在,向主线程发送一个消息,通知它更新地图。

总之就是重写run,以及消息机制的使用。特别注意的就是run中绝对不能写UI的操作,UI的事情只能交给主线程做,所以才需要不断通知。

还有一个要注意线程之间的执行顺序,调试了很久的一个地方,后来发现是因为主线程那边还没计算出结果,但是次线程已经开始新的计算了,所以此线程用到的是主线程没有更新过的旧数据。后来想到的方法就是等主线程算完了,再回来调用次线程的函数。

@Override 
  public void run() 
  { 
		if(find()){
			flag = false;
			int n = 10;
			alpha = 255;
			while(n--!=0){
  		  wait(30);
  		  mHandler.sendEmptyMessage(0);
			}
  		wait(100);
  		mHandler.sendEmptyMessage(1);
  	
	  }
		else if(flag==true){
			swapMap(p1.x,p1.y,p2.x,p2.y);
  		wait(300);
  		mHandler.sendEmptyMessage(2);
	  	}
		else if(flag==false){
	  	p1 = new point(-2,-2);
  	  p2 = new point(-2,-2);
			if(check()==false){
				mHandler.sendEmptyMessage(3);
			}
		}
  }

代码

main.xml

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:background="@drawable/background" 
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@ id/vlayout">
        <TextView
            android:id="@ id/text"
            android:layout_width="fill_parent"
            android:layout_height="40dip"
            android:textSize="18sp"
            android:autoText="true"
            android:textColor="#000000"
            android:capitalize="sentences"
            android:text="开心消消乐" />
</LinearLayout>

MainActivity.java

package com.example.android.market.licensing; 
 
import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.widget.ImageButton; 
import android.widget.LinearLayout; 
import android.widget.TableLayout; 
import android.widget.TableRow; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.view.Gravity; 
import android.view.View; 
 
 
@SuppressLint("NewApi") 
public class MainActivity extends Activity implements Runnable { 
  private static final String TAG = "App"; 
  private point p1 = new point(-2,-2); 
  private point p2 = new point(-2,-2);; 
  private boolean isPoint1 = true; 
  private int map[][] = new int[8][8]; 
  private int id; 
  private int mark[][] = new int[8][8]; 
  private Thread thread; 
  private int num; 
  private int alpha = 255; 
  boolean flag = false; 
  private int score = 0; 
  private TextView text; 
  ImageButton[] btn = new ImageButton[64]; 
   
  private int getStyle(){ 
    num = (int)(1 Math.random()*(7-1 1)); 
    switch(num){ 
    case 1:return id = R.drawable.btn1; 
    case 2:return id = R.drawable.btn2; 
    case 3:return id = R.drawable.btn3; 
    case 4:return id = R.drawable.btn4; 
    case 5:return id = R.drawable.btn5; 
    case 6:return id = R.drawable.btn6; 
    case 7:return id = R.drawable.btn7; 
    default:return id = 0; 
    } 
  } 
 
 
  public MainActivity() { } 
 
  private void initBtn(int i,int j) 
  { 
    btn[8*i j].setBackgroundDrawable 
    (this.getResources().getDrawable(getStyle())); 
    point p = new point(i,j,btn[8*i j],id); 
    btn[8*i j].setTag(p); 
    map[i][j] = num; 
  } 
   
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    LinearLayout vlayout = (LinearLayout)findViewById(R.id.vlayout); 
    TableLayout tlayout = new TableLayout(this); 
    TableRow row[] = new TableRow[8]; 
    for(int i=0;i<8;i  ){ 
      row[i] = new TableRow(this); 
      row[i].setGravity(Gravity.CENTER); 
      for(int j=0;j<8;j  ){ 
        btn[8*i j] = new ImageButton(this); 
        btn[8*i j].setLayoutParams(new TableRow.LayoutParams(38,38)); 
        initBtn(i,j); 
        btn[8*i j].setOnClickListener(listener); 
        row[i].addView(btn[8*i j]); 
      } 
      tlayout.addView(row[i]); 
    } 
    text = new TextView(this);    
    text.setText("分数 : 0"); 
    vlayout.addView(tlayout); 
    vlayout.addView(text); 
    while(find()){ 
      updateState(); 
    } 
    thread = new Thread(this);  
  } 
   
  private void wait(int time) 
  { 
    try { 
      Thread.sleep(time); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
  } 
   
  @Override  
  public void run()  
  {  
    if(find()){ 
      flag = false; 
      int n = 10; 
      alpha = 255; 
      while(n--!=0){ 
        wait(30); 
        mHandler.sendEmptyMessage(0); 
      } 
      wait(100); 
      mHandler.sendEmptyMessage(1); 
     
    } 
    else if(flag==true){ 
      swapMap(p1.x,p1.y,p2.x,p2.y); 
      wait(300); 
      mHandler.sendEmptyMessage(2); 
    } 
    else if(flag==false){ 
      p1 = new point(-2,-2); 
      p2 = new point(-2,-2); 
      if(check()==false){ 
        mHandler.sendEmptyMessage(3); 
      } 
    } 
  }  
 
   void swapImage() 
  { 
    p1.v.setBackgroundDrawable 
    (MainActivity.this.getResources().getDrawable(p2.id)); 
    p2.v.setBackgroundDrawable 
    (MainActivity.this.getResources().getDrawable(p1.id)); 
    int tmp =p1.id; 
    p1.id = p2.id; 
    p2.id = tmp; 
    p1.v.setTag(p1); 
    p2.v.setTag(p2); 
  } 
   
  private void updateBtn(int x1,int y1,int x2,int y2) 
  { 
    map[x1][y1] = map[x2][y2]; 
    point p = (point)(btn[8*x1 y1].getTag()); 
    p.id = ((point)(btn[8*x2 y2].getTag())).id; 
    btn[8*x1 y1].setTag(p); 
    btn[8*x1 y1].setBackgroundDrawable 
    (MainActivity.this.getResources().getDrawable(p.id)); 
  } 
   
  private void updateBtn(int i,int j) 
  { 
    btn[8*i j].setBackgroundDrawable 
    (MainActivity.this.getResources().getDrawable(getStyle())); 
    map[i][j] = num; 
    point p = (point)(btn[8*i j].getTag()); 
    p.id = id; 
    btn[8*i j].setTag(p); 
  } 
 
  private void hideBtn(){ 
    alpha -= 25; 
    for(int i=0;i<8;i  ){ 
      for(int j=0;j<8;j  ){ 
        if(mark[i][j]!=0&&mark[i][j]!=2){ 
          btn[8*i j].getBackground().setAlpha(alpha);      
        } 
      } 
    } 
  } 
 
   
  private void updateState() 
  { 
     
    for(int i=0;i<8;i  ){ 
      for(int j=0;j<8;j  ){ 
        btn[8*i j].getBackground().setAlpha(255);       
      } 
    } 
    for(int i=0;i<8;i  ){ 
      for(int j=0;j<8;j  ){ 
        if(mark[i][j]==1){ 
          for(int k=i;k>0;k--){ 
            updateBtn(k,j,k-1,j); 
          } 
           updateBtn(0,j); 
        } 
        else if(mark[i][j]>=3){ 
          if(i-mark[i][j]>=0) { 
            updateBtn(i,j,i-mark[i][j],j); 
            updateBtn(i-mark[i][j],j); 
          } 
          else{ 
            updateBtn(i,j); 
          } 
        } 
        else if(mark[i][j]==2){
        	updateBtn(i,j);
        }
      } 
    } 
  } 
   
  public Handler mHandler=new Handler()  
  {  
    public void handleMessage(Message msg)  
    {  
      switch(msg.what){ 
        case 0:{ 
          hideBtn(); 
          break; 
        }   
        case 1:{ 
          updateState(); 
          text.setText("分数 "   ((Integer)score).toString()); 
          thread.start(); 
          break; 
        } 
        case 2:{ 
          swapImage(); 
          p1 = new point(-2,-2); 
          p2 = new point(-2,-2); 
          break; 
        } 
        case 3:{ 
          Toast.makeText(MainActivity.this, "已自动生成新地图", Toast.LENGTH_SHORT).show();  
          for(int i=0;i<8;i  ){ 
            for(int j=0;j<8;j  ){ 
              initBtn(i,j); 
            } 
          } 
          while(find()){ 
            updateState(); 
          } 
          break; 
        } 
      } 
      super.handleMessage(msg);  
    }  
  };    
   
  private boolean find() 
  { 
    for(int i=0;i<8;i  ){ 
      for(int j=0;j<8;j  ){ 
        mark[i][j] = 0; 
      } 
    } 
    boolean flag = false; 
    // heng 
    for(int i=0;i<8;i  ){ 
      int count = 1; 
      for(int j=0;j<7;j  ){ 
        if(map[i][j]==map[i][j 1]){ 
          count  ; 
          if(count==3){ 
            flag = true; 
            mark[i][j-1] = 1; 
            mark[i][j] = 1; 
            mark[i][j 1] = 1; 
            score  = 15; 
          } 
          else if(count>3){ 
            mark[i][j 1] = 1; 
            score  = 5; 
          } 
        } 
        else count = 1; 
      } 
    } 
    //shu 
    for(int j=0;j<8;j  ){ 
      int count = 1; 
      for(int i=0;i<7;i  ){ 
        if(map[i][j]==map[i 1][j]){ 
          count  ; 
          if(count==3){ 
            flag = true; 
            if(mark[i][j]==1)score =10; 
            else score  =15; 
            mark[i-1][j] = 3; 
            mark[i][j] = 3; 
            mark[i 1][j] = 3; 
            for(int k=i-5;k>=0;k--){
            	mark[k][j] = 2; 
            }
          } 
          else if(count>3){ 
            mark[i 1][j] = count; 
            for(int k=1;k<count;k  ){ 
              mark[i-k 1][j]  ;              
            } 
            if(i-2*count 2>=0)mark[i-2*count 2][j] = 0;
            score  = 5; 
          } 
        } 
        else count = 1; 
      } 
    } 
    return flag; 
  } 
   
  private boolean check(int i,int j) 
  { 
    //shu 
    int count = 1; 
    if(i>=1&&map[i-1][j]==map[i][j]){ 
      count  ; 
      if(i>=2&&map[i-2][j]==map[i][j]){ 
        count  ; 
      } 
    } 
    if(count>=3)return true; 
    if(i 1<8&&map[i 1][j]==map[i][j]){ 
      count  ; 
      if(i 2<8&&map[i 2][j]==map[i][j]){ 
        count  ; 
      } 
    } 
    if(count>=3)return true; 
     
    //heng 
    count = 1; 
    if(j>=1&&map[i][j-1]==map[i][j]){ 
      count  ; 
      if(j>=2&&map[i][j-2]==map[i][j]){ 
        count  ; 
      } 
    } 
    if(count>=3)return true; 
     
    if(j 1<8&&map[i][j 1]==map[i][j]){ 
      count  ; 
      if(j 2<8&&map[i][j 2]==map[i][j]){ 
        count  ; 
      } 
    } 
    if(count>=3)return true; 
     
    return false; 
  } 
   
  private void swapMap(int x1,int y1,int x2,int y2) 
  { 
    int tmp = map[x1][y1]; 
    map[x1][y1] = map[x2][y2]; 
    map[x2][y2] = tmp; 
  } 
   
  private boolean check() 
  { 
     
    //heng 
    for(int i=0;i<8;i  ){ 
      for(int j=0;j<7;j  ){ 
        swapMap(i,j,i,j 1); 
        if(check(i,j)){ 
          swapMap(i,j,i,j 1); 
          return true; 
        } 
        if(check(i,j 1)){ 
          swapMap(i,j,i,j 1); 
          return true; 
        } 
        swapMap(i,j,i,j 1); 
      } 
    } 
    //shu 
    for(int j=0;j<8;j  ){ 
      for(int i=0;i<7;i  ){ 
        swapMap(i,j,i 1,j); 
        if(check(i,j)){ 
          swapMap(i,j,i 1,j); 
          return true; 
        } 
        if(check(i 1,j)){ 
          swapMap(i,j,i 1,j); 
          return true; 
        } 
        swapMap(i,j,i 1,j); 
      } 
    } 
    return false; 
  } 
   
  ImageButton.OnClickListener listener = new ImageButton.OnClickListener(){//创建监听对象   
    @SuppressLint("NewApi") 
 
    public void onClick(View v) { 
      if(isPoint1){ 
        p1 = (point)v.getTag(); 
        isPoint1 = false; 
      } 
      else { 
        p2 = (point)v.getTag(); 
        isPoint1 = true; 
      } 
     
      if(((p1.x-p2.x==1||p1.x-p2.x==-1)&&p1.y==p2.y)|| 
        (p1.y-p2.y==1||p1.y-p2.y==-1)&&p1.x==p2.x){ 
        flag = true; 
        swapMap(p1.x,p1.y,p2.x,p2.y); 
        swapImage(); 
        thread.start(); 
      } 
    } 
 
  }; 
} 

point.java

package com.example.android.market.licensing;
import android.view.View;
public class point {
	public int x;
	public int y;
	View v;
	int id;
	point(int _x,int _y,View _v,int _id){
		x = _x;
		y = _y;
		v = _v;
		id = _id;
	}
	point(int _x,int _y){
		x = _x;
		y = _y;
	}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.android.market.licensing"
  android:versionCode="2"
  android:versionName="1.1">
  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".MainActivity"
      android:label="@string/app_name"
      android:configChanges="orientation|keyboardHidden">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
  <!-- Devices >= 3 have version of Android Market that supports licensing. -->
  <uses-sdk android:minSdkVersion="3" />
  <!-- Required permission to check licensing. -->
  <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
</manifest>

以上所述是小编给大家介绍的Android开心消消乐代码实例详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对Devmax网站的支持!

Android开心消消乐代码实例详解的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部