wangy 发表于 2021-7-1 08:22:24

【lua教程】自制气泡拖动条

require "import"
import "android.app.*"
import "android.os.*"
import "android.widget.*"
import "android.view.*"

activity.setTitle('自绘制气泡拖动条')
activity.setTheme(android.R.style.Theme_DeviceDefault_Light)--设置md主题

activity.setContentView(loadlayout({
ScrollView;
layout_height="fill";
layout_width="fill";
{
    LinearLayout;
    layout_width="fill";
    gravity="top";
    layout_height="fill";
    orientation="vertical";
    {
      TextView;
      layout_width="fill";
      padding="15dp";
      id="t1";
    };
    {
      View;
      layout_width="fill";
      layout_height="35dp";
      id="animseekBar";
    };
    {
      TextView;
      layout_width="fill";
      padding="15dp";
      id="t2";
    };
};
}
))

import "android.graphics.*"
import "android.graphics.Paint$Style"
import "android.view.animation.*"
import "android.animation.ObjectAnimator"
import "android.animation.PropertyValuesHolder"

dip2px=function(dpValue)
local scale = activity.getResources().getDisplayMetrics().density;
return dpValue * scale + 0.5
end

sp2px=function(spValues)
local fontScale = activity.getResources().getDisplayMetrics().scaledDensity;
return spValues * fontScale+ 0.5
end

getStatusBarHeight=function()
_,statusBarHeight2=xpcall(function()
    local clazz=Class.forName("com.android.internal.R$dimen")
    local object = clazz.newInstance();
    local height = Integer.parseInt(tostring(clazz.getField("status_bar_height").get(object)))
    return this.getResources().getDimensionPixelSize(height);
end,

function(a)
    _,statusBarHeight1=pcall(function()
      local resourceId = this.getResources().getIdentifier("status_bar_height", "dimen", "android");
      if resourceId > 0
      return this.getResources().getDimensionPixelSize(resourceId);
      end
    end,
    function(e)
    end,nil)

end,
nil)
if type(statusBarHeight2):lower()=="number"
    return statusBarHeight2
   elseif type(statusBarHeight1):lower()=="number"
    return statusBarHeight1
   else
    return 0
end
end

BgColor=0xFFBDBDBD--背景色
TopColor=0xFF9C27B0--进度条颜色
TopHandleColor=0xFF9C27B0--滑块颜色
BubblesColor=0xffffffff--气泡字体颜色
BgHeight=dip2px(3)--背景高度
TopHeight=dip2px(4)--进度条高度
TopHandle=dip2px(8)--滑块半径
Max=100--最大值
Dragprogress=0--当前进度
CanvasMargin=dip2px(48)--边距
bubblesTextSize=sp2px(12)--气泡内文字大小
Seekbarids=animseekBar

import "android.content.Context"
mWindowManager = activity.getSystemService(Context.WINDOW_SERVICE);

IndicatorWindow=function(getH,getW)
local mLayoutParams = WindowManager.LayoutParams();
mLayoutParams.gravity = Gravity.START | Gravity.BOTTOM;
mLayoutParams.width =getW;
mLayoutParams.height = getH;
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
--MIUI禁止了开发者使用TYPE_TOAST,Android 7.1.1 对TYPE_TOAST的使用更严格
if Build.MANUFACTURER:lower()~="xiaomi" or Build.VERSION.SDK_INT >= 25
    mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
   else
    mLayoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
end
return mLayoutParams
end


ShowBubbles=function(ids)
local mBubbleView=
{
    LinearLayout;
    layout_width="fill";
    layout_height="fill";
    id="Mcft_Main",
    {
      View,
      id=ids,
      layout_width="54dp";
      layout_height="55dp";
      Visibility=View.GONE,
    }
}
mWindowManager.addView(loadlayout(mBubbleView), IndicatorWindow(0,0) );
end

PaintBubbles=function(progess)
newPaint=Paint()
newPaint.setTextSize(bubblesTextSize)
TextMin=newPaint.measureText(tostring(progess))
Indicator=sp2px(24)
BubblesSize=bubblesTextSize+sp2px(3)
local Paintd=LuaDrawable(function(canvas,paint)
    local cW=canvas.Width
    local cH=canvas.Height
    paint.setAntiAlias(true)
    paint.setStyle(Style.FILL);

    paint.setFakeBoldText(false)
    paint.setTextSize(bubblesTextSize)

    paint.setColor(TopHandleColor)
    local path =Path()
    path.moveTo(Indicator/2,(cH/1.75))
    path.lineTo(cW-(Indicator/2),cH/1.75)
    path.lineTo(cW/2,cH)
    path.close()
    canvas.drawPath(path, paint)

    canvas.drawCircle(cW/2,cH/2,BubblesSize, paint);

    paint.setColor(BubblesColor)
    canvas.drawText(tostring(progess),(cW/2)-(TextMin/2),(cH/2)+(bubblesTextSize/2.5),paint)
end)
return {draw=Paintd,Circlesize=(BubblesSize*2)+Indicator}
end



locationUpdate=function(views,getX,getY,progess)
local outRect1 = Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);
local WidowHeight=outRect1.height()
-Seekbarids.getParent().getHeight()
local clazz=Class.forName("com.android.internal.R$dimen")
local object = clazz.newInstance();
local height = Integer.parseInt(tostring(clazz.getField("status_bar_height").get(object)))
local status_bar_height = this.getResources().getDimensionPixelSize(height);

local BuDraw=PaintBubbles(progess)
views.setBackground(BuDraw.draw)
views.setX(getX+((CanvasMargin/2)-(views.getWidth()/2)))
views.setY((getY+status_bar_height)-(views.getHeight()/2))
--views.setImageDrawable(BuDraw.draw)
local newParams=IndicatorWindow(outRect1.height(),Seekbarids.getParent().getWidth())
mWindowManager.updateViewLayout(views.getParent(), newParams);

end

LogoutBubble=function(view)
mWindowManager.removeViewImmediate(view.getParent());
end


PropertyS=function(a,b,view,isType)
local Attribute_definition = PropertyValuesHolder.ofFloat("method",{ a,b})
local mValueAnimator = ObjectAnimator.ofPropertyValuesHolder({Attribute_definition})
.setStartDelay(0)
.setInterpolator(AnticipateOvershootInterpolator())
.setDuration(500)
mValueAnimator.addUpdateListener({
    onAnimationUpdate=function(animation)
      local Animationaprogress=animation.getAnimatedValue()
      if isType
      view.setVisibility(View.VISIBLE)
      end
      view.setAlpha(Animationaprogress)
      view.setPivotY(view.getHeight()*1.4)
      .setPivotX(view.getWidth()/2)
      .setScaleX(Animationaprogress)
      .setScaleY(Animationaprogress)
      --.setRotationX(-90+(Animationaprogress*90))
      AnimFolatN=Animationaprogress
      SeekbarAmin.invalidateSelf()
    end,
});
mValueAnimator.addListener({
    onAnimationEnd=function()
      if not isType
      view.setVisibility(View.GONE)
      LogoutBubble(view)
      end
    end
}).start()
end


--mBubbleView.setVisibility(GONE); --防闪烁

--mLayoutParams.x = (mBubbleCenterRawX + 0.5f);
--mWindowManager.updateViewLayout(mBubbleView, mLayoutParams);


getWidthPercentage=function(w,max,proges)
local WidthDivision=(w/max)*proges
return {TowX=WidthDivision,Proges=proges}
end

AnimFolatN=0
SeekbarAmin=LuaDrawable(function(canvas,piant,d)
canvasWidth=canvas.getWidth()-CanvasMargin
canvasHeight=canvas.getHeight()

canvas.translate(CanvasMargin/2,0)

piant.setStrokeCap(Paint.Cap.ROUND)
piant.setAntiAlias(true)

--画背景进度条
piant.setColor(BgColor);
piant.setStrokeWidth(BgHeight);
canvas.drawLines({0,canvasHeight/2,canvasWidth,canvasHeight/2},piant)

--画顶部进度条
piant.setColor(TopColor);
piant.setStrokeWidth(TopHeight+((TopHeight/4)*AnimFolatN));
canvas.drawLines({0,canvasHeight/2,getWidthPercentage(canvasWidth,Max,Dragprogress).TowX,canvasHeight/2},piant)

--画滑块
piant.setColor(0x23000000);
canvas.drawCircle(getWidthPercentage(canvasWidth,Max,Dragprogress).TowX,canvasHeight/2,((TopHandle*1.7)*AnimFolatN), piant);
piant.setColor(TopHandleColor);
canvas.drawCircle(getWidthPercentage(canvasWidth,Max,Dragprogress).TowX,canvasHeight/2,TopHandle-((TopHandle)*AnimFolatN), piant);
end)

Seekbarids.background=SeekbarAmin

getPView=function(a)
a=a.getParent()
while a~=nil and not tostring(a):find("ScrollView")
    a=a.getParent()
end
return a==nil and 0 or a.getScrollY()
end

Seekbarids.onTouch=function(v,event)
local Maction=event.getAction()
if Maction==MotionEvent.ACTION_DOWN
    if event.getX()>CanvasMargin/2 and event.getX()<v.getWidth()-CanvasMargin/2
      and event.getY()>(v.getHeight()/2)-TopHandle and event.getY()<(v.getHeight()/2)+TopHandle
      WithinRange=true
      ShowBubbles("bubbles")
      PropertyS(0,1,bubbles,true)
      v.getParent().requestDisallowInterceptTouchEvent(true);
   else
      WithinRange=false
    end
   elseif Maction==MotionEvent.ACTION_MOVE
    if WithinRange
      v.getParent().requestDisallowInterceptTouchEvent(true);
      local getXTo=event.getX()
      local ranger=(event.getX()-CanvasMargin/2)/(v.getWidth()-CanvasMargin)
      --计算百分比
      Dragprogress=tointeger((ranger<=0 and 0 or (ranger>=1 and 1 or ranger))*Max)
      locationUpdate(bubbles,getWidthPercentage(Seekbarids.getWidth()-CanvasMargin,Max,Dragprogress).TowX
      ,Seekbarids.getY()-getPView(v),Dragprogress)
      SeekbarAmin.invalidateSelf()
    end
   elseif Maction==MotionEvent.ACTION_UP
    v.getParent().requestDisallowInterceptTouchEvent(false);
    pcall(function()
      if bubbles and WithinRange
      PropertyS(1,0,bubbles,false)
      end
    end)
end
return true;
end

t1.text=[[
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。
]]
t2.text=[[
2003年10月,Andy Rubin等人创建Android公司,并组建Android团队。
2005年8月17日,Google低调收购了成立仅22个月的高科技企业Android及其团队。安迪鲁宾成为Google公司工程部副总裁,继续负责Android项目。
2007年11月5日,谷歌公司正式向外界展示了这款名为Android的操作系统,并且在这天谷歌宣布建立一个全球性的联盟组织,该组织由34家手机制造商、软件开发商、电信运营商以及芯片制造商共同组成,并与84家硬件制造商、软件开发商及电信营运商组成开放手持设备联盟(Open Handset Alliance)来共同研发改良Android系统,这一联盟将支持谷歌发布的手机操作系统以及应用软件,Google以Apache免费开源许可证的授权方式,发布了Android的源代码。
2008年,在GoogleI/O大会上,谷歌提出了AndroidHAL架构图,在同年8月18号,Android获得了美国联邦通信委员会(FCC)的批准,在2008年9月,谷歌正式发布了Android 1.0系统,这也是Android系统最早的版本。
2009年4月,谷歌正式推出了Android 1.5这款手机,从Android 1.5版本开始,谷歌开始将Android的版本以甜品的名字命名,Android 1.5命名为Cupcake(纸杯蛋糕)。该系统与Android 1.0相比有了很大的改进。
2009年9月,谷歌发布了Android 1.6的正式版,并且推出了搭载Android 1.6正式版的手机HTC Hero(G3),凭借着出色的外观设计以及全新的Android 1.6操作系统,HTC Hero(G3)成为当时全球最受欢迎的手机。Android 1.6也有一个有趣的甜品名称,它被称为Donut(甜甜圈)。
2010年2月,Linux内核开发者Greg Kroah-Hartman将Android的驱动程序从Linux内核“状态树”(“staging tree”)上除去,从此,Android与Linux开发主流将分道扬镳。在同年5月份,谷歌正式发布了Android 2.2操作系统。谷歌将Android 2.2操作系统命名为Froyo,翻译完名为冻酸奶。
2010年10月,谷歌宣布Android系统达到了第一个里程碑,即电子市场上获得官方数字认证的Android应用数量已经达到了10万个,Android系统的应用增长非常迅速。在2010年12月,谷歌正式发布了Android 2.3操作系统Gingerbread (姜饼)。
2011年1月,谷歌称每日的Android设备新用户数量达到了30万部,到2011年7月,这个数字增长到55万部,而Android系统设备的用户总数达到了1.35亿,Android系统已经成为智能手机领域占有量最高的系统。
2011年8月2日,Android手机已占据全球智能机市场48%的份额,并在亚太地区市场占据统治地位,终结了Symbian(塞班系统)的霸主地位,跃居全球第一。
2011年9月,Android系统的应用数目已经达到了48万,而在智能手机市场,Android系统的占有率已经达到了43%。继续在排在移动操作系统首位。谷歌将会发布全新的Android 4.0操作系统,这款系统被谷歌命名为Ice Cream Sandwich(冰激凌三明治)。
2012年1月6日,谷歌Android Market已有10万开发者推出超过40万活跃的应用,大多数的应用程序为免费。Android Market应用程序商店目录在新年首周周末突破40万基准,距离突破30万应用仅4个月。在2011年早些时候,Android Market从20万增加到30万应用也花了四个月。
2013年11月1日,Android4.4正式发布,从具体功能上讲,Android4.4提供了各种实用小功能,新的Android系统更智能,添加更多的Emoji表情图案,UI的改进也更现代,如全新的HelloiOS7半透明效果。
2015年,网络安全公司Zimperium研究人员警告,安卓(Android)存在“致命”安全漏洞,黑客发送一封彩信便能在用户毫不知情的情况下完全控制手机。
2018年10月,谷歌表示,将于2018年12月6日停止Android系统中的Nearby Notifications(附近通知)服务,因为Android用户收到太多的附近商家推销信息的垃圾邮件。
2020年3月,谷歌的Android安全公告中提到,新更新已经提供了CVE-2020-0069补丁来解决针对联发科芯片的一个严重安全漏洞。
]]

来源:代码手册 Robin
页: [1]
查看完整版本: 【lua教程】自制气泡拖动条