双桥区网站制作,职业学校网站模板,美工培训班哪家好,网站推广都有哪些1、Ui开发
笔者的Ui制作的制作的比较麻烦仅供参考#xff0c;在这里使用了多个LinearLayout对屏幕进行了划分。不建议大家这样做最好使用GridLayout会更加快捷简单
笔者大致划分是这样的#xff1a; 使用了四个大框#xff0c;在第四个大框里面有多个小框 最终界面如下在这里使用了多个LinearLayout对屏幕进行了划分。不建议大家这样做最好使用GridLayout会更加快捷简单
笔者大致划分是这样的 使用了四个大框在第四个大框里面有多个小框 最终界面如下
然后在每一个小框写计算机的按键。
代码如下
?xml version1.0 encodingutf-8?
LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticaltools:context.MainActivityLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentImageViewandroid:idid/TwoArrows_Shrinkandroid:layout_width30dpandroid:layout_height30dpandroid:layout_marginTop15dpandroid:layout_marginLeft10dpandroid:srcdrawable/two_arrows_shrink/ImageViewandroid:idid/FourSquaresandroid:layout_width30dpandroid:layout_height30dpandroid:layout_marginLeft220dpandroid:layout_marginTop15dpandroid:srcdrawable/four_squares/ImageViewandroid:idid/ThreePointsandroid:layout_width30dpandroid:layout_height30dpandroid:layout_marginLeft15dpandroid:clickabletrueandroid:layout_marginTop15dpandroid:srcdrawable/three_points//LinearLayoutEditTextandroid:idid/Scanf_EditTextandroid:layout_widthmatch_parentandroid:layout_height0dpandroid:layout_weight3android:backgroundnullandroid:gravitybottom|rightandroid:textandroid:lines1android:inputTypetextVisiblePasswordandroid:textSize40dpandroid:paddingRight16dpandroid:textColorandroid:color/blackandroid:textStylebold /TextViewandroid:idid/Printf_textandroid:layout_widthmatch_parentandroid:layout_height0dpandroid:layout_weight1android:gravitycenter|rightandroid:textandroid:textSize25dpandroid:layout_margin8dpandroid:paddingRight13dpandroid:textColorandroid:color/blackandroid:textStylebold /LinearLayoutandroid:idid/keyboardandroid:layout_widthmatch_parentandroid:layout_height0dpandroid:layout_weight5android:orientationverticalandroid:layout_margin10dp!-- C % - / --LinearLayoutandroid:idid/Oneandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontal!-- C--FrameLayoutandroid:idid/leftCFrmaeandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/leftCandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:text(android:textSize25spandroid:textColorandroid:color/blackandroid:layout_gravitycenterandroid:layout_marginLeft10dpandroid:padding8dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4//FrameLayoutFrameLayoutandroid:idid/RightCFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginStart20dpImageButtonandroid:idid/RightCandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_round/TextViewandroid:layout_width19dpandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:paddingLeft10dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4android:text)android:textColorandroid:color/blackandroid:textSize25sp //FrameLayoutFrameLayoutandroid:idid/DeleteOneFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/DeleteOneandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:textDELandroid:textColorandroid:color/blackandroid:textSize25spandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4//FrameLayoutFrameLayoutandroid:idid/DivisionFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/Divisionandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text➗android:textColorandroid:color/blackandroid:textSize25spandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4//FrameLayout/LinearLayout!-- 7 8 9 x --LinearLayoutandroid:idid/Twoandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:paddingTop15dpFrameLayoutandroid:idid/SevenNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/SevenNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text7android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/EightNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/EightNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text8android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/NineNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/NineNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text9android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/MultiplyFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageViewandroid:idid/Multiplyandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dpandroid:scaleTypecenterInside/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text✖️android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayout/LinearLayout!-- 4 5 6 - --LinearLayoutandroid:idid/Threeandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:paddingTop15dpFrameLayoutandroid:idid/FourNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/FourNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text4android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/FiveNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/FiveNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text5android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/SixNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/SixNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text6android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/BubFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/Subandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text➖android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayout/LinearLayout!-- 1 2 3 --LinearLayoutandroid:idid/Fourandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:paddingTop15dpFrameLayoutandroid:idid/OneNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/OneNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text1android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/TwoNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/TwoNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text2android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/ThreeNumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/ThreeNumandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text3android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/AddFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/addandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_grey_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text➕android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayout/LinearLayout!-- 00 0 . --LinearLayoutandroid:idid/Fiveandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:paddingTop15dpFrameLayoutandroid:idid/CFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/Candroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:textCandroid:textSize25spandroid:textColorandroid:color/blackandroid:layout_gravitycenterandroid:layout_marginLeft10dpandroid:padding8dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4//FrameLayoutFrameLayoutandroid:idid/ONumFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/Oandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:padding8dpandroid:text0android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/PointFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/Pointandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_white_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:paddingBottom10dpandroid:text.android:textColorandroid:color/blackandroid:textSize28dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayoutFrameLayoutandroid:idid/equalFrameandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentImageButtonandroid:idid/equalandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/button_orange_roundandroid:layout_marginStart20dp/TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravitycenterandroid:layout_marginLeft11dpandroid:paddingBottom15dpandroid:textandroid:textColorandroid:color/whiteandroid:textSize45dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4 //FrameLayout/LinearLayout/LinearLayout/LinearLayout我们简单分解一下代码中的重点
1.1 给文本制作阴影并加粗
TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:text(android:textSize25spandroid:textColorandroid:color/blackandroid:layout_gravitycenterandroid:layout_marginLeft10dpandroid:padding8dpandroid:shadowColor#80000000android:shadowDx2android:shadowDy2android:shadowRadius4android:textStylebold/android:shadowColor#80000000表示为该视图的文本添加阴影效果阴影颜色为半透明黑色#80000000。android:shadowDx2表示阴影在水平方向上的偏移量为2个像素。android:shadowDy2表示阴影在垂直方向上的偏移量为2个像素。android:shadowRadius4表示阴影的模糊半径为4个像素。android:textStylebold是对TextView文本视图的一个属性设置用于指定文本的字体样式为粗体加粗。
2.2 制作圆形按钮
在drawable目录下新建xml文件如下
?xml version1.0 encodingutf-8?
shape xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:shapeovalsolid android:colorcolor/orange /size android:height60dp android:width60dp/
/shapeandroid:shape指定图形常用参数有 rectangle: 表示创建一个矩形的形状。oval: 表示创建一个椭圆的形状也就是圆形。line: 表示创建一条线段的形状。ring: 表示创建一个圆环的形状。line: 表示创建一条线段的形状。 solid用于填充颜色
**size **用于指定大小因为是圆形我们这里长宽都要设置为相同
效果如下 2.3 制作点击变色的按钮
笔者在这里没有使用点击变色而是使用了动画后面介绍动画。这里介绍一下怎么点击变色。
首先还是在drawable目录下新建一个xml文件
?xml version1.0 encodingutf-8?
selector xmlns:androidhttp://schemas.android.com/apk/res/android
!-- 定义按下状态的样式 --
item android:state_pressedtrueshape android:shapeovalsolid android:colorcolor/Greywhite /size android:height60dp android:width60dp//shape
/item
!-- 定义普通状态的样式 --
itemshape android:shapeovalsolid android:colorcolor/Greywhite4 /size android:height60dp android:width60dp//shape
/item
/selector设置一个selector如何设置两个item选项设置为android:state_pressedtrue的选项在点击后就会产生对应的变化。
2、点击事件与界面处理
1、禁用输入法修改EditText文本内容 protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);activityMainBinding ActivityMainBinding.inflate(getLayoutInflater());setContentView(activityMainBinding.getRoot());//禁用输入法修改EditText文本内容activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);//传入各个按键//功能键activityMainBinding.C.setOnClickListener(this);activityMainBinding.DeleteOne.setOnClickListener(this);//加减乘除,括号,等于activityMainBinding.add.setOnClickListener(this);activityMainBinding.Sub.setOnClickListener(this);activityMainBinding.Multiply.setOnClickListener(this);activityMainBinding.Division.setOnClickListener(this);activityMainBinding.leftC.setOnClickListener(this);activityMainBinding.RightC.setOnClickListener(this);activityMainBinding.equal.setOnClickListener(this);//数字小数点activityMainBinding.O.setOnClickListener(this);activityMainBinding.OneNum.setOnClickListener(this);activityMainBinding.TwoNum.setOnClickListener(this);activityMainBinding.ThreeNum.setOnClickListener(this);activityMainBinding.FourNum.setOnClickListener(this);activityMainBinding.FiveNum.setOnClickListener(this);activityMainBinding.SixNum.setOnClickListener(this);activityMainBinding.SevenNum.setOnClickListener(this);activityMainBinding.EightNum.setOnClickListener(this);activityMainBinding.NineNum.setOnClickListener(this);activityMainBinding.Point.setOnClickListener(this);activityMainBinding.TwoArrowsShrink.setOnClickListener(this);//长按触发菜单registerForContextMenu(activityMainBinding.ThreePoints);}activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);通过设置 InputType.TYPE_NULLEditText 将不再响应输入法的输入用户无法通过软键盘输入文本内容。这样做的目的通常是为了限制用户只能通过其他途径比如扫码、点击按钮等来输入文本内容而不能直接通过键盘输入。如何我们为每个按钮注册监听事件
2、按键缩放动画和实现震动效果 private void animation(View view) {// 加载缩放动画资源final AnimatorSet scaleAnimation (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);//实现震动效果/*** Vibrator vibrator(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);* vibrator.vibrate(new long[]{0,100}, -1);* 从Android API level 26开始Vibrator类的vibrate()方法被弃用推荐使用VibrationEffect来实现震动效果。VibrationEffect类提供了更灵活和可控的震动方式。*/// 获取Vibrator实例Vibrator vibrator (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);// 判断Android版本是否大于等于API 26if (Build.VERSION.SDK_INT Build.VERSION_CODES.O) {// 创建VibrationEffect对象指定震动模式和震动时长100msVibrationEffect vibrationEffect VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);// 开始震动vibrator.vibrate(vibrationEffect);} else {// Android版本低于API 26使用老版本的vibrate方法//震动时间为100msvibrator.vibrate(100);}// 开始执行缩放动画scaleAnimation.setTarget(view);scaleAnimation.start();scaleAnimation.addListener(new AnimatorListenerAdapter() {Overridepublic void onAnimationEnd(Animator animation) {// 在缩放动画结束时创建还原动画并执行还原动画ObjectAnimator restoreAnimationX ObjectAnimator.ofFloat(view, scaleX, 1.0f);ObjectAnimator restoreAnimationY ObjectAnimator.ofFloat(view, scaleY, 1.0f);AnimatorSet restoreAnimation new AnimatorSet();restoreAnimation.playTogether(restoreAnimationX, restoreAnimationY);restoreAnimation.start();}});}首先加载缩放动画资源。
final AnimatorSet scaleAnimation (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);scale_animation是animator下设置的动画属性
具体设置如下
?xml version1.0 encodingutf-8?
set xmlns:androidhttp://schemas.android.com/apk/res/androidobjectAnimatorandroid:propertyNamescaleXandroid:valueFrom1.0android:valueTo0.9android:duration100android:repeatCount0android:repeatModerestartandroid:interpolatorandroid:anim/accelerate_decelerate_interpolator /objectAnimatorandroid:propertyNamescaleYandroid:valueFrom1.0android:valueTo0.9android:duration100android:repeatCount0android:repeatModerestartandroid:interpolatorandroid:anim/accelerate_decelerate_interpolator /
/setandroid:propertyName: 定义要动画化的属性的名称。在这里scaleX 和 scaleY 分别表示水平和垂直方向的缩放。android:valueFrom: 定义动画的起始值。这里起始值为 1.0表示不缩放。android:valueTo: 定义动画的结束值。这里结束值为 0.9表示缩放到原始大小的 0.9 倍。android:duration: 定义动画的持续时间以毫秒为单位。这里持续时间为 100 毫秒即缩放动画的过程为 0.1 秒。android:repeatCount: 定义动画重复的次数。这里设置为 0表示动画不重复。android:repeatMode: 定义动画重复的模式。这里设置为 restart表示每次重复动画都从头开始。android:interpolator: 定义动画的插值器用于控制动画的变化速率。这里使用了 Android 系统自带的 accelerate_decelerate_interpolator 插值器表示动画先加速后减速。
这个 XML 文件定义了两个属性动画分别是在水平方向和垂直方向上的缩放动画效果。在 Android 应用中你可以通过加载这个 XML 文件来应用这个缩放动画让指定的视图如 View 或 ImageView在缩放动画的作用下由原始大小缩放到 0.9 倍的大小。
制作动画时创建了一个 scaleAnimation 缩放动画然后给该动画添加了一个监听器 AnimatorListenerAdapter。在监听器的 onAnimationEnd() 方法中当缩放动画结束时会执行还原动画。
大致逻辑
创建缩放动画 scaleAnimation 并设置属性动画的相关参数。给 scaleAnimation 添加一个监听器在缩放动画结束时执行还原动画。创建两个 ObjectAnimator 分别对 view 的 scaleX 和 scaleY 属性进行动画处理将 view 的缩放比例恢复为原始大小1.0f。将还原动画 restoreAnimation 中的两个动画一起播放。
3、实现显示框字体大小变化的动画
当我们计算完结果后我们让计算的结果变大计算的算式变小
private void DisplayFrameAnimation(View Little_big, View Big_little) { // 加载动画资源,从25变到40AnimatorSet Little_Big (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_40);// 设置目标视图Little_Big.setTarget(Little_big);// 启动动画Little_Big.start();// 加载动画资源,从40变到25AnimatorSet Big_Little (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_25);// 设置目标视图Big_Little.setTarget(Big_little);// 启动动画Big_Little.start();
}AnimatorInflater: 这是一个用于加载属性动画的类。它提供了一个方法 loadAnimator()可以通过指定资源ID加载属性动画。
this: 这里的 this 指的是当前的上下文即所在的 Activity。R.animator.text_size_40_25: 这是指定的属性动画资源的资源ID。在这里text_size_40_25 是一个位于 res/animator 目录下的 XML 文件它定义了一组属性动画。
同样这样的操作需要动画文件我们在这里介绍一下字体大小由25变化到40的
?xml version1.0 encodingutf-8?
!-- text_size_change.xml --
set xmlns:androidhttp://schemas.android.com/apk/res/androidobjectAnimatorandroid:propertyNametextSizeandroid:valueTypefloatTypeandroid:valueFrom25android:valueTo40android:duration500/
/setset这是属性动画的根元素用于定义属性动画集合。在这里我们只有一个动画所以只有一个 objectAnimator 子元素。objectAnimator这是一个对象动画元素用于定义属性动画。它有以下属性 android:propertyNametextSize这是要动画化的属性名称即视图的文本大小属性 textSize。android:valueTypefloatType这是动画值的类型这里是浮点数类型用于表示文本大小。android:valueFrom25这是动画的起始值即文本大小的初始值为 25。android:valueTo40这是动画的结束值即文本大小的目标值为 40。android:duration500这是动画的持续时间即从起始值到结束值的过渡时间为 500 毫秒。
3、逻辑与算法
1.1 按钮点击结果的分析与处理
package com.example.computermoblie;import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Service;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.InputType;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;import com.example.computermoblie.databinding.ActivityMainBinding;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;public class MainActivity extends AppCompatActivity implements View.OnClickListener {// 计算器储存总数据的上限public ListString SumNumber new ArrayList();//计算器存储的数字上限private StringBuilder Number new StringBuilder();//当前输入框字体大小,初始状态为40dpprivate int SIzeOfText 40;public ActivityMainBinding activityMainBinding;private boolean GetEqual false; //表示没有按下等号private boolean NegativeSymbol false; //表示不是负数的符号public String ret; //运算结果private static final String Del Delete; //表示删除键Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);activityMainBinding ActivityMainBinding.inflate(getLayoutInflater());setContentView(activityMainBinding.getRoot());//禁用输入法修改EditText文本内容activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);//传入各个按键//功能键activityMainBinding.C.setOnClickListener(this);activityMainBinding.DeleteOne.setOnClickListener(this);//加减乘除,括号,等于activityMainBinding.add.setOnClickListener(this);activityMainBinding.Sub.setOnClickListener(this);activityMainBinding.Multiply.setOnClickListener(this);activityMainBinding.Division.setOnClickListener(this);activityMainBinding.leftC.setOnClickListener(this);activityMainBinding.RightC.setOnClickListener(this);activityMainBinding.equal.setOnClickListener(this);//数字小数点activityMainBinding.O.setOnClickListener(this);activityMainBinding.OneNum.setOnClickListener(this);activityMainBinding.TwoNum.setOnClickListener(this);activityMainBinding.ThreeNum.setOnClickListener(this);activityMainBinding.FourNum.setOnClickListener(this);activityMainBinding.FiveNum.setOnClickListener(this);activityMainBinding.SixNum.setOnClickListener(this);activityMainBinding.SevenNum.setOnClickListener(this);activityMainBinding.EightNum.setOnClickListener(this);activityMainBinding.NineNum.setOnClickListener(this);activityMainBinding.Point.setOnClickListener(this);activityMainBinding.TwoArrowsShrink.setOnClickListener(this);//长按触发菜单registerForContextMenu(activityMainBinding.ThreePoints);}Overridepublic void onClick(View view) {final int Id view.getId();// 调用按键动画animation(view);//退出if(Id R.id.TwoArrows_Shrink){finish();}//功能按钮if (Id R.id.C) {//清空显示activityMainBinding.ScanfEditText.setText();ret ;activityMainBinding.PrintfText.setText(ret);//清空储存的内容SumNumber.clear();Number.setLength(0);//还原字体大小SIzeOfText 40;} else {if (Id R.id.leftC) {if (!GetEqual) {if (Number.length() 0) {char cat Number.charAt(Number.length() - 1);if (cat ! . !Character.isDigit(cat)) {SumNumber.add(();} else {//左括号前面没有符号只有数字默认为乘号//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Number.setLength(0);SumNumber.add(×);SumNumber.add(();}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {SumNumber.add(×);SumNumber.add(();} else {SumNumber.add(();}}//开头就使用括号的情况if (SumNumber.isEmpty()){SumNumber.add(();}}}if (Id R.id.RightC) {if (!GetEqual) {if (Number.length() 0) {char cat Number.charAt(Number.length() - 1);if (cat ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Number.setLength(0);SumNumber.add());//使得按下后动态计算结果DynamicCalculation();}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);Log.d(DEL1, SumNumber.toString());if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {SumNumber.add());//使得按下后动态计算结果DynamicCalculation();}}}}if (Id R.id.DeleteOne) {if (!GetEqual) {if (Number.length() 0) {Number.deleteCharAt(Number.length() - 1);} else if (SumNumber.size() 0) {try {Number.setLength(0);Number.append(SumNumber.remove(SumNumber.size() - 1));Number.deleteCharAt(Number.length() - 1);}catch (NumberFormatException e){Log.d(Number, 出现空值);}}else {ret ;activityMainBinding.PrintfText.setText(ret);}//删除所有数据后清除结果if (SumNumber.isEmpty()){ListComputing(Del);}}else {ListComputing(Del);}//使得按下后动态计算结果DynamicCalculation();}//加减乘除if (Id R.id.add) {if (!GetEqual) {if (Number.length() 0) {if (Number.charAt(Number.length() - 1) ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Number.setLength(0);SumNumber.add();}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add();}}} else {ListComputing();}}if (Id R.id.Sub) {if (!GetEqual) {if (Number.length() 0) {if (Number.charAt(Number.length() - 1) ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(-);}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(-);} else if (str.equals(×) || str.equals(÷)||str.equals(()) {Number.append(-);}}else {Number.append(-);}} else {ListComputing(-);}}if (Id R.id.Multiply) {if (!GetEqual) {if (Number.length() 0) {if (Number.charAt(Number.length() - 1) ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(×);}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(×);}}} else {ListComputing(×);}}if (Id R.id.Division) {if (!GetEqual) {if (Number.length() 0) {if (Number.charAt(Number.length() - 1) ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(÷);}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (!str.equals() !str.equals(-) !str.equals(×) !str.equals(÷) !str.equals(()) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Log.d(String1, String.valueOf(Number));Number.setLength(0);SumNumber.add(÷);}}} else {ListComputing(÷);}}//数字if (Id R.id.OneNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(1);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.TwoNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(2);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.ThreeNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(3);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.FourNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(4);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.FiveNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(5);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.SixNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(6);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.SevenNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(7);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.EightNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(8);// //使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.NineNum) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(9);//使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.O) {ClearDisplay();//清空显示if (!SumNumber.isEmpty()) {String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {SumNumber.add(×);}}Number.append(0);//使得按下数字后动态计算结果DynamicCalculation();}if (Id R.id.Point) {if (Number.length() 0) {int t 0;for (int i 0; i Number.length(); i) {if (Number.charAt(i) .) {t;}}if (t 1) {Number.append(.);}}}if (Id R.id.equal) {if (Number.length() 0) {if (Number.charAt(Number.length() - 1) ! .) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Number.setLength(0);//表示等号已经按下用于清除文本框GetEqual true;//计算结果ReversePolish reversePolish new ReversePolish(SumNumber);ret reversePolish.EvaluatePostfixExpressions();//加载大小变化的动画DisplayFrameAnimation(activityMainBinding.PrintfText, activityMainBinding.ScanfEditText);}} else if (!SumNumber.isEmpty()) {//判断是不是存在两个相邻的操作String str SumNumber.get(SumNumber.size() - 1);if (str.equals())) {//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}Number.setLength(0);//表示等号已经按下用于清除文本框GetEqual true;//计算结果ReversePolish reversePolish new ReversePolish(SumNumber);ret reversePolish.EvaluatePostfixExpressions();//加载大小变化的动画DisplayFrameAnimation(activityMainBinding.PrintfText, activityMainBinding.ScanfEditText);}}}//显示文本框内容if (Number ! null) {StringBuilder builder new StringBuilder();for (String str : SumNumber) {builder.append(str);}builder.append(Number);activityMainBinding.ScanfEditText.setText(builder);activityMainBinding.PrintfText.setText(ret);MaxDisplayFrameAnimation(activityMainBinding.ScanfEditText);}}}//按键缩放动画和实现震动效果private void animation(View view) {// 加载缩放动画资源final AnimatorSet scaleAnimation (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);//实现震动效果/*** Vibrator vibrator(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);* vibrator.vibrate(new long[]{0,100}, -1);* 从Android API level 26开始Vibrator类的vibrate()方法被弃用推荐使用VibrationEffect来实现震动效果。VibrationEffect类提供了更灵活和可控的震动方式。*/// 获取Vibrator实例Vibrator vibrator (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);// 判断Android版本是否大于等于API 26if (Build.VERSION.SDK_INT Build.VERSION_CODES.O) {// 创建VibrationEffect对象指定震动模式和震动时长VibrationEffect vibrationEffect VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);// 开始震动vibrator.vibrate(vibrationEffect);} else {// Android版本低于API 26使用老版本的vibrate方法vibrator.vibrate(100);}// 开始执行缩放动画scaleAnimation.setTarget(view);scaleAnimation.start();scaleAnimation.addListener(new AnimatorListenerAdapter() {Overridepublic void onAnimationEnd(Animator animation) {// 在缩放动画结束时创建还原动画并执行还原动画ObjectAnimator restoreAnimationX ObjectAnimator.ofFloat(view, scaleX, 1.0f);ObjectAnimator restoreAnimationY ObjectAnimator.ofFloat(view, scaleY, 1.0f);AnimatorSet restoreAnimation new AnimatorSet();restoreAnimation.playTogether(restoreAnimationX, restoreAnimationY);restoreAnimation.start();}});}// 显示框的动画效果private void DisplayFrameAnimation(View Little_big, View Big_little) {/*** SIzeOfText 40 由上方40-25 下方25-40* SIzeOfText 30 由上方30-25 下方25-30* SIzeOfText 25 由上方不变 下方25-30*/if (SIzeOfText 40) {// 加载动画资源,从25变到40AnimatorSet Little_Big (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_40);// 设置目标视图Little_Big.setTarget(Little_big);// 启动动画Little_Big.start();// 加载动画资源,从40变到25AnimatorSet Big_Little (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_25);// 设置目标视图Big_Little.setTarget(Big_little);// 启动动画Big_Little.start();} else if (SIzeOfText 30) {Log.d(SIzeOfText, String.valueOf(SIzeOfText));// 加载动画资源,从25变到30AnimatorSet Little_Big (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_30);// 设置目标视图Little_Big.setTarget(Little_big);// 启动动画Little_Big.start();// 加载动画资源,从30变到25AnimatorSet Big_Little (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_30_25);// 设置目标视图Big_Little.setTarget(Big_little);// 启动动画Big_Little.start();} else if (SIzeOfText 25) {// 加载动画资源,从25变到30AnimatorSet Little_Big (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_30);// 设置目标视图Little_Big.setTarget(Little_big);// 启动动画Little_Big.start();}}//显示框的字符达到指定长度使得一行无法放下private void MaxDisplayFrameAnimation(View Big_littleView) {int MaxDigit 0;for (String str : SumNumber) {MaxDigit str.length();}MaxDigit Number.length();Log.d(StrSize, num: MaxDigit);if (MaxDigit 10) {SIzeOfText 30; //字体变化为30// 加载动画资源,从40变到30AnimatorSet Big_Little (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_30);// 设置目标视图Big_Little.setTarget(Big_littleView);// 启动动画Big_Little.start();}if (MaxDigit 10 MaxDigit 25) activityMainBinding.ScanfEditText.setTextSize(30);if (MaxDigit 15) {SIzeOfText 25; //字体变化为25// 加载动画资源,从30变到25AnimatorSet Big_Little (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_30_25);// 设置目标视图Big_Little.setTarget(Big_littleView);// 启动动画Big_Little.start();activityMainBinding.ScanfEditText.setTextSize(25);}if (MaxDigit 15) activityMainBinding.ScanfEditText.setTextSize(25);}//加载菜单Overridepublic void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {Log.d(Tag, 加载菜单);getMenuInflater().inflate(R.menu.function, menu);super.onCreateContextMenu(menu, v, menuInfo);}//注册菜单点击事件Overridepublic boolean onContextItemSelected(NonNull MenuItem item) {Log.d(Tag, 点击事件);final int Id item.getItemId();if (Id R.id.Log) {//历史记录} else if (Id R.id.SetUp) {//设置}return super.onContextItemSelected(item);}//清空显示private void ClearDisplay() {//还原显示框大小activityMainBinding.ScanfEditText.setTextSize(40);activityMainBinding.PrintfText.setTextSize(30);//表示已经按下后重新输入数字的情况if (GetEqual) {GetEqual false;activityMainBinding.ScanfEditText.setText();ret ;//清空储存的内容SumNumber.clear();Number.setLength(0);//还原字体大小SIzeOfText 40;}}//连续计算的情况private void ListComputing(String str) {if (str.equals(Del)) {GetEqual false;//还原显示框大小activityMainBinding.ScanfEditText.setTextSize(40);activityMainBinding.PrintfText.setTextSize(30);SIzeOfText 40;ret ;if (Number.length() 0) {Number.deleteCharAt(Number.length() - 1);} else if (SumNumber.size() 0) {try {Number.setLength(0);Number.append(SumNumber.remove(SumNumber.size() - 1));Number.deleteCharAt(Number.length() - 1);}catch (NumberFormatException e){Log.d(Number, 出现空值);}}} else if (!ret.equals(Error)){GetEqual false;//还原显示框大小activityMainBinding.ScanfEditText.setTextSize(40);activityMainBinding.PrintfText.setTextSize(30);//清空储存的内容SumNumber.clear();Number.setLength(0);//还原字体大小SIzeOfText 40;SumNumber.add(ret);SumNumber.add(str);ret ;}}//使得按下数字后动态计算结果private void DynamicCalculation() {if(!SumNumber.isEmpty() SumNumber.size() 0){//将number的数据放入Sumnumberif (!Number.equals() Number ! null) {//保存数据try {SumNumber.add(String.valueOf(Number));} catch (NumberFormatException e) {Log.d(Number, 出现空值);}}//计算当前结果ReversePolish reversePolish new ReversePolish(SumNumber);ret reversePolish.EvaluatePostfixExpressions();//删去暂时存放的数据SumNumber.remove(SumNumber.size() - 1);}}
}
2.2 中缀表达式转后缀表达式使用逆波兰计算
package com.example.computermoblie;import android.content.Intent;
import android.util.Log;
import android.view.View;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Stack;public class ReversePolish {public ListString SumNumber;StackBigDecimal SymbolStack new Stack();//表示没有计算错误的情况private boolean Error false;public static final int LeftBrack 0; //左括号优先级public static final int AandS 1; //加减法public static final int MandD 2; //乘除public static final int RightBrack 3; //右括号优先级//中缀转后缀public QueueString InfixToSuffix() {QueueString queue new ArrayDeque();StackString swapStack new Stack();for (int i 0; i SumNumber.size(); i) {String isStr SumNumber.get(i);if (!IsSymbol(isStr)) {queue.add(isStr); // 将数字直接添加到输出队列中} else {if (swapStack.isEmpty() || isStr.equals(()) {swapStack.push(isStr);} else if (isStr.equals())) {if(!swapStack.isEmpty()){while (!swapStack.peek().equals(()) {queue.add(swapStack.pop());}swapStack.pop(); // 弹出 (}} else {while (!swapStack.isEmpty() JudgmentPriority(swapStack.peek(), isStr)) {queue.add(swapStack.pop());}swapStack.push(isStr);}}}while (!swapStack.isEmpty()) {queue.add(swapStack.pop());}return queue;}public String EvaluatePostfixExpressions() {Error false; // 表示运算未发现错误BigDecimal ret null; // 表示最后的运算结果QueueString queue InfixToSuffix(); // 获取后缀表达式Log.d(WQWQ,queue.toString());while (!queue.isEmpty()) {String str queue.remove();if (!IsSymbol(str)) {//保存数据try {BigDecimal number new BigDecimal(str);SymbolStack.push(number);} catch (NumberFormatException e) {Log.d(Number,出现空值);}} else {if (SymbolStack.size() 2) {Error true; // 栈中元素不足2个运算错误break;}BigDecimal op2 SymbolStack.pop();BigDecimal op1 SymbolStack.pop();BigDecimal result null;switch (str) {case :result op1.add(op2);break;case -:result op1.subtract(op2);break;case ×:result op1.multiply(op2);break;case ÷:if (op2.compareTo(BigDecimal.ZERO) 0) {Error true; // 除数为零运算错误break;}result op1.divide(op2, 3, RoundingMode.HALF_UP);break;default:Error true; // 非法的运算符运算错误break;}if (Error) {break;} else {SymbolStack.push(result);}}}if (Error) {return Error; // 出现错误后直接返回错误信息} else {if (!SymbolStack.isEmpty()) {ret SymbolStack.pop();}// 使用toEngineeringString()方法将结果输出为工程计数法return ret.toEngineeringString();}}public ReversePolish(ListString sumNumber) {SumNumber sumNumber;}//判断是否为符号public boolean IsSymbol(String str) {boolean isSymbole false;if (str.equals()) {isSymbole true;} else if (str.equals(-)) {isSymbole true;} else if (str.equals(×)) {isSymbole true;} else if (str.equals(÷)) {isSymbole true;} else if (str.equals(()) {isSymbole true;} else if (str.equals())) {isSymbole true;}return isSymbole;}//判断优先级public boolean JudgmentPriority(String PreantStr, String SunStr) {//默认PreantStr优先级小于SunStrboolean value false;if (SymbolValue(PreantStr) SymbolValue(SunStr)) {value true;}return value;}//判断属于什么符号public int SymbolValue(String str) {int Value LeftBrack;if (str.equals()) {Value AandS;} else if (str.equals(-)) {Value AandS;} else if (str.equals(×)) {Value MandD;} else if (str.equals(÷)) {Value MandD;} else if (str.equals(()) {Value LeftBrack;} else if (str.equals())) {Value RightBrack;}return Value;}public ListString getSumNumber() {return SumNumber;}
}主要代码如上此外笔者代码存在一个空指针异常NullPointerException的问题问题出在SumNumber如果多次使用删除键反复输入数据在删除这种测试操作会导致空指针异常使得操作SumNumber的代码逻辑访问到空指针。这个问题笔者解决了很久都没找到问题所在如有找到问题所在烦请告知笔者不胜感激。具体异常信息如下
根据日志信息异常的原因是在某个地方尝试调用一个对象的toString()方法但该对象为空null因此无法执行该方法。
根据提供的堆栈跟踪信息可以看出空指针异常NullPointerException在以下方法中被抛出 com.example.computermoblie.ReversePolish.InfixToSuffix(ReversePolish.java:45) com.example.computermoblie.ReversePolish.EvaluatePostfixExpressions(ReversePolish.java:69) com.example.computermoblie.MainActivity.onClick(MainActivity.java:189) com.example.computermoblie.MainActivity.DynamicCalculation(MainActivity.java:872)