本文实例为大家分享了android实现简单计算器的具体代码,供大家参考,具体内容如下

// 日期:2014/9/26
 
// 首先,人们的输入习惯为中缀表达式。为了便于计算,程序会将中缀表达式会转换为后缀表达式
 
////////////////////////////////////////////////////////////////////////////////////////
// 目前软件还存在
// 1.输入运算数和运算符不匹配时,崩溃的现象。(如:只输入一个操作数)
// 2.一个数字中重复输入两个小数点。(如4.5.6)
// 这两个重大的bug,后续会继续修改
 
////////////////////////////////////////////////////////////////////////////////////////
// 只有一种布局。这也会在后续考虑完善。
// 若有其他不完善的地方,请指正。(╯▽╰)
 
 
package com.example.countea;
 
import android.os.Bundle;          //不太明白到底是啥
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
 
import android.widget.Toast;         // 显示版权信息
import java.util.Iterator;         // 迭代器
import java.util.LinkedList;         // 双向列表
 
public class MainActivity extends Activity {
 private EditText content;
 private EditText operaline;
 private Double first_num = 0.0;       // 第一个操作数
 private Double sec_num = 0.0;       // 第二个操作数
 //无法设置bool型变量?????
 private static int equal_flg = 0;       // 等号的状态:FALSE表示未按过等号,TRUE表示已经按过等号
 private double negative_mark = 0;       // 正负数标记
 LinkedList<String> Infix = new LinkedList<String>();  // 对content进行解析,即存放中缀表达式的链表
 LinkedList<String> Suffix = new LinkedList<String>();  // 存放后缀表达式的链表
 LinkedList<Double> Suffix_Num = new LinkedList<Double>(); // 存放后缀表达式的数字链表
 LinkedList<String> OP = new LinkedList<String>();   // 1.作为临时存放运算符的链表;2.存放后缀表达式的运算符
 
 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 
 
 // 处理"c"清屏按钮功能
 Button clear = (Button) findViewById(R.id.clear);
 clear.setOnClickListener(new OnClickListener() {
 
 @Override
 public void onClick(View v) 
 {
 // TODO Auto-generated method stub
 content = (EditText) findViewById(R.id.content);
 content.setText("");
 equal_flg = 0;
 
 first_num = 0.0;
 sec_num = 0.0;
 OP.clear();
 Suffix.clear();
 Suffix_Num.clear();
 operaline.setText("");
 operaline.setSelection(operaline.getText().length());
 }
 });
 
 // 处理CE删除当前操作按钮功能
 Button current_clear = (Button) findViewById(R.id.current_clear);
  current_clear.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) 
 {
 // TODO Auto-generated method stub
 content = (EditText) findViewById(R.id.content);
 content.setText("");
 equal_flg = 0;
 
 first_num = 0.0;
 sec_num = 0.0;
 OP.clear();
 Suffix.clear();
 Suffix_Num.clear();
 }
 });
 
 // 处理back退格按钮功能
 Button back = (Button) findViewById(R.id.back);
 back.setOnClickListener(new OnClickListener() {
 
 @Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 content = (EditText) findViewById(R.id.content);
 String str = content.getText().toString();
 if (content.getText().length() != 0)
  content.setText(str.substring(0, str.length() - 1));
  content.setSelection(content.getText().length()); //暂时不知道有什么用,若编辑框为空则无需处理,验证是否会导致异常退出
 }
 });
 
 // 考虑对符号键和数字键是否需要分开实现
 // 实现对"0123456789. -*/()"按钮的监听;而对"="按钮的监听则采用匿名内部类的方法在onCreate()方法体内进行
 OnClickListener mylistener = new OnClickListener() 
 {
 @Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 Button num_btn = (Button) v;
 content = (EditText) findViewById(R.id.content);
 
 // 储存界面运算式
 String content_str = content.getText().toString();
 
 // 当已经有一次运算时,再次按“数字键”清除上次的结果
 if((1==equal_flg)/*&&(num_btn.getText().toString().equals("1")
  ||num_btn.getText().toString().equals("2")
  ||num_btn.getText().toString().equals("3")
  ||num_btn.getText().toString().equals("4")
  ||num_btn.getText().toString().equals("5")
  ||num_btn.getText().toString().equals("6")
  ||num_btn.getText().toString().equals("7")
  ||num_btn.getText().toString().equals("8")
  ||num_btn.getText().toString().equals("9")
  ||num_btn.getText().toString().equals("0"))*/)
 {
  content.setText("0");
  content.setSelection(content.getText().length());
  Toast.makeText(MainActivity.this,"还真执行了!", Toast.LENGTH_LONG).show();
  equal_flg=0; 
 }
 
 // 重复输入运算符、括号或者“.”的处理
 if((" ".equals(content_str.substring(content_str.length()-1,content_str.length()))
  ||"-".equals(content_str.substring(content_str.length()-1,content_str.length()))
  ||"*".equals(content_str.substring(content_str.length()-1,content_str.length()))
  ||"/".equals(content_str.substring(content_str.length()-1,content_str.length()))
  ||".".equals(content_str.substring(content_str.length()-1,content_str.length())))&&((num_btn.getText().toString().equals(" ")
  ||num_btn.getText().toString().equals("-")
  ||num_btn.getText().toString().equals("*")
  ||num_btn.getText().toString().equals("/")
  ||num_btn.getText().toString().equals("."))))
 {
  content_str=content_str.substring(0, content_str.length()-1);
  //Toast.makeText(MainActivity.this,"手抖了吗?", Toast.LENGTH_LONG).show();
 } 
 
 // 重复按“.”的处理
 /*if(num_btn.getText().toString().equals("."))
 {
  // 如果界面只有数字,则改变当前数字的符号
  if("0"!=content_str)
  {
  judge_str = turn_mark(judge_str);  
  content.setText(judge_str);
  content.setSelection(content.getText().length());
  // Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
  }
 }*/ 
 
 // 不实现拼接
 // 当前数据为0,下次输入为非0数字或括号
 if("0".equals(content.getText().toString())
  &&!(num_btn.getText().toString().equals(" "))
  &&!(num_btn.getText().toString().equals("-"))
  &&!(num_btn.getText().toString().equals("*"))
  &&!(num_btn.getText().toString().equals("/"))
  &&!(num_btn.getText().toString().equals(".")))
 {
  // 强制转换测试是否有危险??????
  content_str = (String) num_btn.getText();
  //Toast.makeText(MainActivity.this,num_btn.getText(), Toast.LENGTH_LONG).show();
 }
 
 // 实现拼接
 // 当前数据为0且下次输入为运算符或点号
 else
 {
  content_str  = num_btn.getText();
  //Toast.makeText(MainActivity.this,content_str, Toast.LENGTH_LONG).show();
 }
 content.setText(content_str);
 content.setSelection(content.getText().length());
 }
 };
 
 // 无需特别处理的数字和符号按钮
 Button num1 = (Button) findViewById(R.id.num_1);
 num1.setOnClickListener(mylistener);
 Button num2 = (Button) findViewById(R.id.num_2);
 num2.setOnClickListener(mylistener);
 Button num3 = (Button) findViewById(R.id.num_3);
 num3.setOnClickListener(mylistener);
 Button num4 = (Button) findViewById(R.id.num_4);
 num4.setOnClickListener(mylistener);
 Button num5 = (Button) findViewById(R.id.num_5);
 num5.setOnClickListener(mylistener);
 Button num6 = (Button) findViewById(R.id.num_6);
 num6.setOnClickListener(mylistener);
 Button num7 = (Button) findViewById(R.id.num_7);
 num7.setOnClickListener(mylistener);
 Button num8 = (Button) findViewById(R.id.num_8);
 num8.setOnClickListener(mylistener);
 Button num9 = (Button) findViewById(R.id.num_9);
 num9.setOnClickListener(mylistener);
 Button point = (Button) findViewById(R.id.point);
 point.setOnClickListener(mylistener);
 Button left = (Button) findViewById(R.id.left);
 left.setOnClickListener(mylistener);
 Button right = (Button) findViewById(R.id.right);
 right.setOnClickListener(mylistener);
 Button plus = (Button) findViewById(R.id.plus);
 plus.setOnClickListener(mylistener);
 Button subtract = (Button) findViewById(R.id.subs);
 subtract.setOnClickListener(mylistener);
 Button multiply = (Button) findViewById(R.id.multiply);
 multiply.setOnClickListener(mylistener);
 Button divide = (Button) findViewById(R.id.division);
 divide.setOnClickListener(mylistener);
 
 
 // 对按钮0的处理
 Button num0 = (Button) findViewById(R.id.num_0);
 num0.setOnClickListener(new OnClickListener() 
 {
 @Override
 public void onClick(View v) 
 {
 content = (EditText) findViewById(R.id.content);
 // 当前编辑框中的值为0
 if ("0".equals(content.getText().toString())||""== content.getText().toString())
 {
  content.setText("0");
 }
 // 编辑框已有非0数据
 else
 {
  String str = content.getText().toString();
   str  = "0";
   content.setText(str);
 }
 content.setSelection(content.getText().length());
 // Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
 } 
 });
 
 // 对“-/ ”的处理
 Button mark_sign = (Button) findViewById(R.id.mark_sign);
 mark_sign.setOnClickListener(new OnClickListener() 
 {
 @Override
 public void onClick(View v) 
 {
 
 content = (EditText) findViewById(R.id.content);
 String judge_str = content.getText().toString();
 
 // 如果界面只有数字,则改变当前数字的符号
 if("0"!=judge_str&&((-1==judge_str.indexOf(" "))
  ||(-1==judge_str.indexOf("-")))
  ||(-1==judge_str.indexOf("*"))
  ||(-1==judge_str.indexOf("/"))
  ||(-1==judge_str.indexOf("("))
  ||(-1==judge_str.indexOf(")")))
 {
  judge_str = turn_mark(judge_str);  
  content.setText(judge_str);
  content.setSelection(content.getText().length());
  // Toast.makeText(MainActivity.this,"GET", Toast.LENGTH_LONG).show();
 }
 } 
 });
 // 实现"="按钮的功能
 Button equal = (Button) findViewById(R.id.equal);
 equal.setOnClickListener(new OnClickListener() 
 {
 @Override
 public void onClick(View v) 
 {
 // TODO Auto-generated method stub
 content = (EditText) findViewById(R.id.content);
 operaline = (EditText) findViewById(R.id.operatline);
 // str_Infix为待转换的中缀表达式
 String str_Infix = content.getText().toString();
 // 友好的界面提示处理
 String equate = str_Infix;
 equate  = "=";
 operaline.setText(equate);
 operaline.setSelection(content.getText().length());
 // 调用Analysis函数对content进行解析
 MainActivity.this.Analysis(str_Infix);   
 System.out.println(Infix);
 // 至此,中缀表达式已存放到Infix链表中
 
 Iterator<String> it = Infix.iterator();
 while (it.hasNext()) 
 {  
  String tmp_str = it.next();
  if (isNum(tmp_str)) 
  {
   // 如果是数字或小数点则直接进入Suffix链表;
  Suffix.addLast(tmp_str);
  }
  // 如果不是数字或小数点的话;
  else 
  {
  int OP_level = OP.isEmpty() ? 0 : getLevel(OP.getLast());
  // tmp_str比OP的顶运算符优先级高则入OP
  if (getLevel(tmp_str) > OP_level) 
  {
  OP.addLast(tmp_str);
  }
  // tmp_str比OP的顶运算符优先级低
  else 
  {
  // tmp_str为")",则将OP一直出栈直到遇到"("
  if (getLevel(tmp_str) == -1) 
  {
  String temp_OP = OP.removeLast();
  while (getLevel(temp_OP) != -2) {
   Suffix.addLast(temp_OP);
   temp_OP = OP.removeLast();
  }
  }
  // tmp_str为"(",则直接入OP
  else if (getLevel(tmp_str) == -2) 
  {
  OP.addLast(tmp_str);
  }
  // tmp_str比OP_level优先级低又不是"(" ")",
  // 则OP一直出栈直到OP为空或tmp_str比OP_level优先级高
  else 
  {
  String str2 = OP.removeLast();
  while (getLevel(str2) >= OP_level) 
  {
   Suffix.addLast(str2);
   if (OP.isEmpty()) 
   {
   break;
   }
   str2 = OP.removeLast();
  }
  OP.addLast(tmp_str);
  }
  }
  }
 }
 Infix.clear();// 清空Infix链表
 // OP中剩余的元素出OP进入Suffix
 while (!OP.isEmpty()) 
 {
  Suffix.addLast(OP.removeLast());
 }
 System.out.println(Suffix);
 // 至此,中缀表达式已全部转化为后缀表达式Suffix
 
 // 后缀表达式的计算过程???未指定操作数时 默认为0
 while (!(Suffix.isEmpty())) 
 {
  String count_str = Suffix.removeFirst();
  if (isOP(count_str)) 
  {
  char compare_ch = count_str.charAt(0);
  first_num = Suffix_Num.removeLast();
  sec_num = Suffix_Num.removeLast();
  switch (compare_ch) {
  case '*':
  Suffix_Num.addLast(sec_num * first_num);
  break;
  case '/':
  // 测试注意除数和被除数的顺序
  if (first_num != 0) 
  {
  Suffix_Num.addLast(sec_num / first_num);
  break;
  } else 
  {
  content = (EditText) findViewById(R.id.content);
  // ?????无法再编辑框内,设置提示
  content.setText("∞");
  content.setSelection(content.getText().length());
  }
  case ' ':
  Suffix_Num.addLast(sec_num   first_num);
  break;
  case '-':
  Suffix_Num.addLast(sec_num - first_num);
  break;
  }
  } 
  else 
  {
  Suffix_Num.addLast(Double.parseDouble(count_str));
  }
 }
 // 至此,求得的结果已在Suffix_Num列表中
 
 // 这部分的逻辑为 result 存放从Suffix_Num列表中取出的数据,处理结果后显示到界面上。
 Double result=Suffix_Num.removeFirst();
 String res_str=Double.toString(result);
 
 if("0".equals(res_str.substring(res_str.length()-1,res_str.length())))
 {
  if(".".equals(res_str.substring(res_str.length()-2,res_str.length()-1)))
  {
  res_str=res_str.substring(0,res_str.length()-2);
  //Toast.makeText(MainActivity.this,res_str, Toast.LENGTH_LONG).show();
  };
 };
  content.setText(res_str);
  content.setSelection(content.getText().length());
  equal_flg = 1;
  if("-".equals(res_str.substring(0,1)))
  res_str=turn_mark(res_str);
 }
 });
 // 操作数清空?????android有自动释放机制?
 first_num = 0.0;
 sec_num = 0.0;
 OP.clear();
 Suffix.clear();
 Suffix_Num.clear();
 }
 
 // 自定义isNum()方法来检测元素是否为数值
 public boolean isNum(String str) {
 int num = 0;
 for (int i = 0; i < str.length(); i  ) {
 String strr = str.substring(i, i   1);
 if (strr.equals("0") || strr.equals("1") || strr.equals("2")
  || strr.equals("3") || strr.equals("4") || strr.equals("5")
  || strr.equals("6") || strr.equals("7") || strr.equals("8")
  || strr.equals("9") || strr.equals("."))
 num = num   1;
 }
 if (num == str.length())
 return true;
 else
 return false;
 }
 
 // 自定义isOP()方法来检测Suffix列表的元素是否为运算符
 public boolean isOP(String strr) {
 if (strr.equals(" ") || strr.equals("-") || strr.equals("*")
 || strr.equals("/"))
 return true;
 else
 return false;
 }
 
 // 定义运算符的等级
 public int getLevel(String str) {
 if (str.equals("*") || str.equals("/")) {
 return 2;
 } else if (str.equals(" ") || str.equals("-")) {
 return 1;
 } else if (str.equals("(")) {
 return -2;
 } else if (str.equals(")")) {
 return -1;
 } else {
 return 0;
 }
 }
 
 // 改变正负号
 public String turn_mark(String str) 
 {
 String temp = "(";
 temp  = "-";
 temp  = str;
 temp  = ")";
 str = temp;
 return str;
 }
 
 // 实现对编辑框内容以数字和操作符分开储存
 public void Analysis(String str) {
 String sub = "";
 
 for (int i = 0; i < str.length(); i  ) 
 {
 // 用substring遍历需要解析的数组
 String strr = str.substring(i, i   1);
 if (isNum(strr)) 
 {
 sub  = strr;
 }
 else 
 {
 if (sub != "")
 {
  Infix.addLast(sub); // 首先sub进Infix
  sub = "";    // 将sub清空
 }
 Infix.addLast(strr);  // " -*/" "(" ")" 则直接进Infix表
 }
 }
 // ?????测试for下面的IF是否是因为循环无法判断最后一个数
 if (isNum(str.substring(str.length() - 1))) {
 Infix.addLast(sub);   // 首先sub进Infix
 sub = "";      // 将sub清空
 }
 
 }
 
 @Override
 public boolean onCreateOptionsMenu(Menu menu) 
 {
 /*
 * // Inflate the menu; this adds items to the action bar if it is
 * present. getMenuInflater().inflate(R.menu.main, menu);
 */
 menu.add(0, 1, 1, "退出");
 menu.add(0, 2, 2, "关于");
 menu.add(0, 3, 3, "帮助");
 return super.onCreateOptionsMenu(menu);
 /* return true; */
 }
 
 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 // TODO Auto-generated method stub
 //finish();
 if (item.getItemId() == 2) 
 {
 // 利用Toast来显示提示信息
 Toast.makeText(MainActivity.this,"作者:歡 联系:cdch@gmail.com", Toast.LENGTH_LONG).show();
 }
 if (item.getItemId() == 3) 
 {
 // 利用Toast来显示提示信息
 Toast.makeText(MainActivity.this,"适用于一般算数运算!", Toast.LENGTH_LONG).show();
 }
 
 return super.onOptionsItemSelected(item);
 };
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持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实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部