30 ClipDrawable

本文介绍如何使用ClipDrawable实现图片从中间向两边展开的动画效果。通过定义ClipDrawable资源文件并结合定时器更新level属性,逐步展示图片内容。

ClipDrawable代表从其它位图上截取一个"图片片段",XML中的根元素为<clip.../>,截取的方向由clipOrientation控制

下面以一个慢慢展开的图片为例

先定义一个ClipDrawable资源文件my_clip.xml

<?xml version="1.0" encoding="utf-8"?>  
<clip xmlns:android="http://schemas.android.com/apk/res/android"   
    android:drawable="@drawable/fengjing"  
    android:clipOrientation="horizontal"  
    android:gravity="center">  
</clip> 

接下来在主界面main.xml中的imageview中引用它

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
    <!-- 这里imageView的src定义为clipdrawable资源 -->  
    <ImageView  
        android:id="@+id/image"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:src="@drawable/my_clip" />  
</LinearLayout> 

主界面代码

package WangLi.Resouce.ClipDrawableTest;  
  
import java.util.Timer;  
import java.util.TimerTask;  
  
import android.app.Activity;  
import android.graphics.drawable.ClipDrawable;  
import android.os.Bundle;  
import android.os.Handler;  
import android.os.Message;  
import android.widget.ImageView;  
  
public class ClipDrawableTest extends Activity {  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        ImageView imageview = (ImageView)findViewById(R.id.image);  
        //获取图片所显示的ClipDrawble对象  
        final ClipDrawable drawable = (ClipDrawable)imageview.getDrawable();  
        final Handler handler = new Handler()  
        {  
            public void handleMessage(Message msg)  
            {  
                if(msg.what == 0x1233)  
                {  
                    //修改ClipDrawable的level值  
                    drawable.setLevel(drawable.getLevel() +200);  
                }  
            }  
        };  
        final Timer timer = new Timer();  
        timer.schedule(new TimerTask()  
        {  
            public void run()  
            {  
                Message msg = new Message();  
                msg.what = 0x1233;  
                //发送消息,通知应用修改ClipDrawable对象的level值  
                handler.sendMessage(msg);  
                //取消定时器  
                if(drawable.getLevel() >= 10000)  
                {  
                    timer.cancel();  
                }  
            }  
        },0,300);  
    }  
}  

显示的效果就是图片从中间往两边慢慢展开

转载于:https://www.cnblogs.com/YyuTtian/p/5440482.html

为什么在下面代码中,图片是从中间向两边展开而不是从底部向上展开package com.example.bulbpage import android.graphics.drawable.ClipDrawable import android.os.Bundle import android.view.GestureDetector import android.view.MotionEvent import androidx.appcompat.app.AppCompatActivity import com.example.bulbpage.databinding.ActivityMainBinding import com.google.android.material.bottomsheet.BottomSheetBehavior class MainActivity : AppCompatActivity() { private var _binding: ActivityMainBinding? = null private val binding get() = _binding!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) _binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val btnBottomSheet = binding.btnBottomSheet val llBottomSheet = binding.llBottomSheet // val pullImageView = binding.pull // val seekBar = binding.seekBar // val lampProgressView = binding.lampProgressView // // // 隐藏 SeekBar // seekBar.visibility = View.GONE // // // 设置 SeekBar 最大值 // seekBar.max = 100 // // // SeekBar 控制 LampProgressView(已有逻辑) // seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { // override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { // val ratio = progress / 100f // lampProgressView.setProgress(ratio) // } // // override fun onStartTrackingTouch(seekBar: SeekBar?) {} // override fun onStopTrackingTouch(seekBar: SeekBar?) {} // }) // // // 绑定 LampProgressView 触摸事件 // lampProgressView.setOnTouchListener { view, event -> // when (event.action) { // MotionEvent.ACTION_DOWN, // MotionEvent.ACTION_MOVE -> { // val touchY = event.y // val viewHeight = view.height.toFloat() // // // 计算百分比(从下往上) // val progress = 1 - (touchY / viewHeight) // val clampedProgress = progress.coerceIn(0f…1f) // // // 更新 SeekBar 的进度 // seekBar.progress = (clampedProgress * seekBar.max).toInt() // // // 更新 LampProgressView 显示 // lampProgressView.setProgress(clampedProgress) // // return@setOnTouchListener true // } // } // false // } // // // BottomSheet 相关逻辑(保持不变) // // pullImageView.clipToOutline = true // pullImageView.outlineProvider = object : ViewOutlineProvider() { // override fun getOutline(view: View, outline: Outline) { // val cornerRadius = 80f // val path = Path() // val width = view.width.toFloat() // val height = view.height.toFloat() // // path.moveTo(0f, height) // path.lineTo(0f, cornerRadius) // path.quadTo(width / 2, 0f, width, cornerRadius) // path.lineTo(width, height) // path.close() // outline.setConvexPath(path) // } // } // // // behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { // override fun onStateChanged(bottomSheet: View, newState: Int) { // updatePullSelectorState(newState) // } // // override fun onSlide(bottomSheet: View, slideOffset: Float) { // // 可选:滑动动画或透明度变化 // } // }) val gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() { private var startY = 0f private var totalDelta = 0f private val maxDelta = 150 * resources.displayMetrics.density // 灯泡图高度 override fun onDown(e: MotionEvent): Boolean { startY = e.y return true } override fun onScroll( e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float ): Boolean { totalDelta += distanceY // 向上滑动为正 totalDelta = totalDelta.coerceIn(0f, maxDelta) val percent = (totalDelta / maxDelta) * 100 val level = (percent * 100).toInt() (binding.lampImageView.drawable as? ClipDrawable)?.level = level binding.percentText.text = "${percent.toInt()}%" return true } }) // 设置触摸监听器,让整个页面都能响应手势 binding.root.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) } val behavior = BottomSheetBehavior.from(llBottomSheet) updatePullSelectorState(behavior.state) btnBottomSheet.setOnClickListener { if (behavior.state == BottomSheetBehavior.STATE_EXPANDED) { behavior.state = BottomSheetBehavior.STATE_COLLAPSED } else { behavior.state = BottomSheetBehavior.STATE_EXPANDED } } } private fun updatePullSelectorState(state: Int) { when (state) { BottomSheetBehavior.STATE_EXPANDED -> { binding.pull.isSelected = true } else -> { binding.pull.isSelected = false } } } override fun onDestroy() { super.onDestroy() _binding = null } } <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=“http://schemas.android.com/apk/res/android” xmlns:app=“http://schemas.android.com/apk/res-auto” android:layout_width=“match_parent” android:layout_height=“match_parent” android:background=“@color/background_gray”> <!--背景--> <ImageView android:id="@+id/background_on" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/on" android:visibility="visible" /> <ImageView android:id="@+id/imageView" android:layout_width="180dp" android:layout_height="244dp" android:layout_gravity="center_horizontal" android:layout_marginTop="207dp" android:src="@drawable/bulbbottom" /> <!--control--> <ImageView android:id="@+id/lampImageView" android:layout_width="wrap_content" android:layout_height="150dp" android:adjustViewBounds="true" android:scaleType="centerInside" android:src="@drawable/clip_bulb" /> <TextView android:id="@+id/percentText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="50%" android:textSize="18sp" android:textColor="#000" android:layout_marginTop="16dp"/> <!-- 灯泡显示比例 View --> <!-- <com.example.bulbpage.bulbcontrol.LampProgressView--> <!-- android:id="@+id/lampProgressView"--> <!-- android:layout_width="180dp"--> <!-- android:layout_height="228dp"--> <!-- android:layout_gravity="center_horizontal"--> <!-- android:layout_marginTop="190dp" />--> <!-- 灯泡底座--> <ImageView android:layout_width="180dp" android:layout_height="658dp" android:layout_gravity="center_horizontal" android:src="@drawable/bulbonbottom" app:layout_anchor="@+id/background_on" app:layout_anchorGravity="center" /> <!-- <SeekBar--> <!-- android:id="@+id/seekBar"--> <!-- android:layout_width="0dp"--> <!-- android:layout_height="0dp"--> <!-- android:layout_gravity="bottom"--> <!-- android:layout_marginBottom="100dp"--> <!-- android:max="100"--> <!-- android:progress="0"--> <!-- android:visibility="gone" />--> <!--开关按钮--> <ImageButton android:id="@+id/switch_button" android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center_horizontal" android:layout_marginTop="476dp" android:background="@android:color/transparent" android:scaleType="centerInside" android:src="@drawable/switchselector" /> <!--隐藏栏开关--> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="60dp" android:gravity="center" android:orientation="vertical"> <Button android:id="@+id/btn_bottom_sheet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="BottomSheet" android:textAllCaps="false" /> </LinearLayout> <!--隐藏toolbar--> <LinearLayout android:id="@+id/ll_bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" app:behavior_peekHeight="110dp" app:layout_behavior="@string/bottom_sheet_behavior"> <ImageView android:id="@+id/pull" android:layout_width="match_parent" android:layout_height="30dp" android:background="@color/white" android:clickable="false" android:focusable="false" android:gravity="center" android:paddingTop="15dp" android:src="@drawable/pullselector" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:background="@color/white" android:gravity="center" android:text="c" android:textSize="20sp" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:background="@android:color/holo_orange_dark" android:gravity="center" android:text="b" android:textSize="20sp" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:background="@android:color/holo_green_light" android:gravity="center" android:text="c" android:textSize="20sp" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:background="@android:color/holo_orange_dark" android:gravity="center" android:text="b" android:textSize="20sp" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:background="@android:color/holo_orange_light" android:gravity="center" android:text="c" android:textSize="20sp" /> </LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout> <!-- res/drawable/clip_bulb.xml --> <!-- res/drawable/clip_bulb.xml -->
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值