Android中 activity怎么调用自定义view中重绘的方法?

android中,在activity里调用自定义view的postInvalidate()和invalidate()方法,自定义view中并没有重新绘制,当然在自定义view本类中调用是可以实现重新绘制的。求大神指导,是我调用方法不对? 还是有其他重新绘制方法可以供activity调用?

7个回答

代码发出来 我帮你看看

poorkick
onlyloveyd 回复One_Sun: 应该是你没有把这个View放到布局中的缘故,你可以尝试在主布局中添加自定义的这个View,然后在onCreate方法中使用findViewById的方式获取对象,应该就正常了
3 年多之前 回复
One_Sun
One_Sun 你好,代码我也发评论了,你可以看一下,谢谢。
3 年多之前 回复
One_Sun
One_Sun 你好,我截了几张图,你看一下,在评论里,我感觉图片比较明了,如果不够详细,你告诉我我给你发代码。
3 年多之前 回复

你看看你操作的view是不是其它的view,对象错了

One_Sun
One_Sun 你好,没有调错对象,我打Log都看了,我担心是线程间问题,也打印线程id了,是在一个线程执行也不行,而且线程也起了,也试着用handler进行处理了,还是不行。。
3 年多之前 回复

这个没重新绘制原因有很多,比如,android系统没有检测到你的控件发生变化,他就不会执行onDraw进行重绘。或者在内部的缓存中,发现缓存的大小并
没改变,也不会导致重绘。所以,我们可以强制清除系统缓存等数据,让view去重绘。
可调用如下方法进行试验:
forceLayout();
measure(0, 0);
requestLayout();
invalidate();

One_Sun
One_Sun 你好,我刚刚试了试你提的这几种方法,但是还是没有效果,目前这边情况是我在自定义view类中类构建时起一个线程,然后让线程停止一秒,改变标志位可以停止绘制。再然后让线程停止几秒,再重新调用postInvalidate()方法,也能实现重新绘制。只是在activity中向自定义view发送消息通知自定义view重新绘制时没有效果,不用handler发送消息,写方法调用也没有效果。你一会再看评论,我给你截几张图你看看,谢谢。
3 年多之前 回复

activity中的OnCreate自定义View中onDraw方法里加的判断自定义view中接收activity中发送消息的handler

package com.example.windows.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

private DynamicWaveTwo dynamicWaveTwo;
private Message message;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    dynamicWaveTwo = new DynamicWaveTwo(MainActivity.this,null);


    //在此处发送消息给自定义view,是我想开始时让自定义view先绘制一秒之后然后再停止绘制。
    //这个通知消息传给自定义view之后是可以停止绘制的。是ok的。
    message=dynamicWaveTwo.drawHandler.obtainMessage();
    message.what = 1 ;
    dynamicWaveTwo.drawHandler.sendMessageDelayed(message,1000);
    Log.i("TAG", "onCreate 已发送"+Thread.currentThread().getId());



    Button bt = (Button)findViewById(R.id.bt1);
    bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //问题在这里,我在点击按钮之后发送一条消息,自定义view也能收到消息,标志位也修改成功。
            //但是在自定义view中调用重新绘制方法就是绘制不成功。
            message=dynamicWaveTwo.drawHandler.obtainMessage();
            message.what = 0 ;
            dynamicWaveTwo.drawHandler.sendMessage(message);
            Log.i("TAG", "已点击"+Thread.currentThread().getId());


            // Log.i("TAG", "已点击");
            //DynamicWaveTwo.a = 0;


            //new DynamicWaveTwo(MainActivity.this,null).continueDraw(0);

            //如何在activity里调用自定义view的重绘方法

          /*  new Thread(new Runnable() {
                @Override
                public void run() {
                    Log.i("TAG", "已点击");
                    new DynamicWaveTwo(MainActivity.this,null).continueDraw(0);
                }
            }).start();*/

/* new Thread(new Runnable() {
@Override
public void run() {
Message message=dynamicWaveTwo.drawHandler.obtainMessage();
message.what = 0 ;
dynamicWaveTwo.drawHandler.sendMessage(message);
//dynamicWaveTwo.drawHandler.sendMessageDelayed();
}
}).start();*/

        }
    });
}

}

全部代码,这是Activity中的

package com.example.windows.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class DynamicWaveTwo extends View {

// 波纹颜色
private static final int WAVE_PAINT_COLOR = 0x880000aa;
// y = Asin(wx+b)+h
private static final float STRETCH_FACTOR_A = 23;//影响振幅,数值越大,波纹振幅越深

private static final int OFFSET_Y = 0;
// 第一条水波移动速度
private static final int TRANSLATE_X_SPEED_ONE = 16;//原值7
// 第二条水波移动速度
private static final int TRANSLATE_X_SPEED_TWO = 8;//原值5
private float mCycleFactorW;

private int mTotalWidth, mTotalHeight;
private float[] mYPositions;
private float[] mResetOneYPositions;
private float[] mResetTwoYPositions;
private int mXOffsetSpeedOne;
private int mXOffsetSpeedTwo;
private int mXOneOffset;
private int mXTwoOffset;
private int new_STRETCH_FACTOR_A;

private Paint mWavePaint;
private Paint mWaveTowPaint;

private DrawFilter mDrawFilter;

public static int a = 0;



//自定义view类中
public  Handler drawHandler = new Handler() {

    public void handleMessage(android.os.Message msg) {

        int b = msg.what;

        //接收activity的消息,并修改标志位,实现控制。
        //停止绘制的判读。没有问题,可以停止绘制。
        if(b == 1){

            Log.i("TAG","handleMessage 1"+Thread.currentThread().getId());
            a = b;


            //问题在这里,修改完标志位,调用重新绘制方法,自定义view不能实现重绘。
            //Log 打印标志位也修改成功,就是不能重新绘制。
        }else if(b == 0){

            Log.i("TAG","handleMessage 0"+Thread.currentThread().getId());
            a = b;
            // continueDraw();
            // postInvalidate();
            // invalidate();

            //forceLayout();
            //measure(0, 0);
            //requestLayout();
            //invalidate();
            postInvalidate();
        }

    }

};


public DynamicWaveTwo(Context context, AttributeSet attrs) {
    super(context, attrs);
    // 将dp转化为px,用于控制不同分辨率上移动速度基本一致
    mXOffsetSpeedOne = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_ONE);
    mXOffsetSpeedTwo = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_TWO);

    // 将dp转化为px,用于控制不同分辨率上振幅高度基本一致
    new_STRETCH_FACTOR_A = UiUtils.dipToPx(context, (int)STRETCH_FACTOR_A);

    // 初始绘制波纹的画笔
    mWavePaint = new Paint();
    mWaveTowPaint = new Paint();
    // 去除画笔锯齿
    mWavePaint.setAntiAlias(true);
    mWaveTowPaint.setAntiAlias(true);
    // 设置风格为实线
    mWavePaint.setStyle(Style.FILL);
    mWaveTowPaint.setStyle(Style.FILL);
    // 设置画笔颜色
    //mWavePaint.setColor(WAVE_PAINT_COLOR);
    //mWavePaint.setColor(Color.RED);

    mWavePaint.setColor(Color.rgb(41, 182, 246));
    //设置透明度,注意一定要在设置颜色之后设置透明度,不然没有效果。
    mWavePaint.setAlpha(0x80);//其取值范围是0---255,数值越小,越透明,颜色上表现越淡。实际上当设成10以下就会有透明的效果了。
    //这里设置成0x80,0x代表转换为十六进制,设置为八十,证明透明度就是二十,设置为0,证明透明度就是百分百,设置的数值越小,越透明
    // 这个项目UI要求的透明度为%20,所以就设置为80。

    mWaveTowPaint.setColor(Color.rgb(235, 98, 55));
    mWaveTowPaint.setAlpha(0x90);

    mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);


  /*  new Thread(new Runnable() {
        @Override
        public void run() {

            try {
                Thread.sleep(1000);
                a = 1;
               *//* Thread.sleep(9000);
                a = 0;
                //postInvalidate();

                continueDraw();

//

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }).start();*/




}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 从canvas层面去除绘制时锯齿
    canvas.setDrawFilter(mDrawFilter);
    resetPositonY();
    for (int i = 0; i < mTotalWidth; i++) {

        // 减400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果
        // 绘制第一条水波纹     (demo想法)

        //实际上就是绘制两个不同的动画,然后进行移动,重叠处像是产生了波纹动画的效果,我们可以把第一个减400改为减100,第二个还是减400,运行就可以看出效果。
        //两个都减100,产生的效果就是整个动画高度没有那么高了。  (个人想法)
        canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i] - 100, i,
                mTotalHeight,
                mWavePaint);

        // 绘制第二条水波纹
        canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - 100, i,
                mTotalHeight,
                mWaveTowPaint);
    }

    // 改变两条波纹的移动点
    mXOneOffset += mXOffsetSpeedOne;
    mXTwoOffset += mXOffsetSpeedTwo;

    // 如果已经移动到结尾处,则重头记录
    if (mXOneOffset >= mTotalWidth) {
        mXOneOffset = 0;
    }
    if (mXTwoOffset > mTotalWidth) {
        mXTwoOffset = 0;
    }

    // 引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片
    //postInvalidate();
    // postInvalidateDelayed(100); //延时30毫秒重新绘制


    //在onDraw方法中,为了方便activity中对绘制实现控制,
    //所以加的判断条件
    if(a == 0){
        postInvalidate();
    }



}

private void resetPositonY() {
    // mXOneOffset代表当前第一条水波纹要移动的距离
    int yOneInterval = mYPositions.length - mXOneOffset;
    // 使用System.arraycopy方式重新填充第一条波纹的数据
    System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, yOneInterval);
    System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval, mXOneOffset);

    int yTwoInterval = mYPositions.length - mXTwoOffset;
    System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0,
            yTwoInterval);
    System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval, mXTwoOffset);

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    // 记录下view的宽高
    mTotalWidth = w;
    mTotalHeight = h;
    // 用于保存原始波纹的y值
    mYPositions = new float[mTotalWidth];
    // 用于保存波纹一的y值
    mResetOneYPositions = new float[mTotalWidth];
    // 用于保存波纹二的y值
    mResetTwoYPositions = new float[mTotalWidth];

    // 将周期定为view总宽度
    mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);

    // 根据view总宽度得出所有对应的y值
    for (int i = 0; i < mTotalWidth; i++) {
        mYPositions[i] = (float) (new_STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y);
    }
}

public void continueDraw(){

    //a = a1;
    //Log.i("TAG","continueDraw     " + String.valueOf(a).toString());
    Log.i("TAG", "continueDraw     " + String.valueOf(a).toString());
    //this.postInvalidate();
    //invalidate();
    //requestLayout();
    postInvalidate();
}

}

全部代码,这是自定义View。 谢谢。

应该是你没有把这个View放到布局中的缘故,你可以尝试在主布局中添加自定义的这个View,然后在onCreate方法中使用findViewById的方式获取对象,应该就正常了,用你发的代码 做我上面的修改是OK的

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Android中 activity调用自定义view中的重绘方法不起作用?
-
Android如何在activity中设置自定义view中的数据
-
Android 自定义view中可以改变activity的数据吗?或者说传值给Activity
-
Activity中调用 自定义LinearLayout布局文件方法
-
Android在自定义View控制Activity里控件
-
Android中能在一个自定义view中注册广播并发出广播吗
-
Android 动态切换标题栏里用户自定义view , view里button的点击事件不响应
-
Android 自定义View 参数
-
android 关于自定义view的问题
-
Android自定义控件在ListView中不显示
-
Android自定义view失败
-
是用一个Activity对应一个界面,还是一个个自定义的View对应一个界面
-
自定义组件:在使用自定义组件的Activity修改Paint画笔画的长方形颜色
-
Android 自定义View点击事件
-
如何从主activity打开我自定义的类
-
Android自定义Button的OnKeyDown方法没反应
-
在一个自定义的对话框中如何使用一个 list view?
-
Android Studio自定义布局中的Button不响应点击事件
-
android 中自定义GridView的使用
-
Linux文件操作高频使用命令
文章目录0.新建操作:1.查看操作2.删除操作3.复制操作4.移动操作:5.重命名操作:6.解压压缩操作 0.新建操作: mkdir abc #新建一个文件夹 touch abc.sh #新建一个文件 1.查看操作 查看目录: ll #显示目录文件详细信息 查看文件内容: cat|head|tail命令 cat abc.txt #查看abc的内容 head -5 abc.txt #...
程序员实用工具网站
目录 1、搜索引擎 2、PPT 3、图片操作 4、文件共享 5、应届生招聘 6、程序员面试题库 7、办公、开发软件 8、高清图片、视频素材网站 9、项目开源 10、在线工具宝典大全 程序员开发需要具备良好的信息检索能力,为了备忘(收藏夹真是满了),将开发过程中常用的网站进行整理。 1、搜索引擎 1.1、秘迹搜索 一款无敌有良心、无敌安全的搜索引擎,不会收集私人信息,保...
LeetCode解题汇总目录
此篇为LeetCode刷题的汇总目录,方便大家查找,一起刷题,一起PK交流! 已解题目 考点 LeetCode 1. 两数之和(哈希) LeetCode 2. 两数相加(单链表反转) LeetCode 9. 回文数 LeetCode 11. 盛最多水的容器(双指针) LeetCode 15. 三数之和 LeetCode 17. 电话号码的字母组合(回溯...
全球最厉害的 14 位程序员!
来源 | ITWorld 整理自网络全球最厉害的 14 位程序员是谁?今天就让我们一起来了解一下吧,排名不分先后。01. Jon Skeet个人名望:程序技术问答网站 S...
从入门到精通,Java学习路线导航
引言 最近也有很多人来向我"请教",他们大都是一些刚入门的新手,还不了解这个行业,也不知道从何学起,开始的时候非常迷茫,实在是每天回复很多人也很麻烦,所以在这里统一作个回复吧。 Java学习路线 当然,这里我只是说Java学习路线,因为自己就是学Java的,对Java理当很熟悉,对于其它方面,我也不是很了解。 基础阶段 首先是基础阶段,在基础阶段,我们必须掌握Java基础,Mysql数据库,Ora...
二十出头,老气横秋
有的时候,我们希望年轻人成熟一点,不要巨婴,不要总是等着别人来解救,要自立,要有担当。但有时候吧,发现有些年轻人,似乎过于成熟了,二十来岁的人,感觉怎么就老气横秋的。1、...
我花了一夜用数据结构给女朋友写个H5走迷宫游戏
起因 又到深夜了,我按照以往在csdn和公众号写着数据结构!这占用了我大量的时间!我的超越妹妹严重缺乏陪伴而 怨气满满! 而女朋友时常埋怨,认为数据结构这么抽象难懂的东西没啥作用,常会问道:天天写这玩意,有啥作用。而我答道:能干事情多了,比如写个迷宫小游戏啥的! 当我码完字准备睡觉时:写不好别睡觉! 分析 如果用数据结构与算法造出东西来呢? ...
五分钟小知识:为什么说 ++i 的效率比 i++ 高?
点击蓝色“五分钟学算法”关注我哟加个“星标”,天天中午 12:15,一起学算法作者 | 守望先生来源 | 编程珠玑前言不知道你是否听说过 ++i 比 i++ 快的说法,真...
什么是大公司病(太形象了)
点击蓝色“五分钟学算法”关注我哟加个“星标”,天天中午 12:15,一起学算法作者 | 南之鱼来源 | 芝麻观点(chinamkt)所谓大企业病,一般都具有机构臃肿、多重...
代码整洁 vs 代码肮脏
写出整洁的代码,是每个程序员的追求。《clean code》指出,要想写出好的代码,首先得知道什么是肮脏代码、什么是整洁代码;然后通过大量的刻意练习,才能真正写出整洁的代码。 WTF/min是衡量代码质量的唯一标准,Uncle Bob在书中称糟糕的代码为沼泽(wading),这只突出了我们是糟糕代码的受害者。国内有一个更适合的词汇:屎山,虽然不是很文雅但是更加客观,程序员既是受害者也是加害者。 对...
让程序员崩溃的瞬间(非程序员勿入)
今天给大家带来点快乐,程序员才能看懂。 来源:https://zhuanlan.zhihu.com/p/47066521 1. 公司实习生找 Bug 2.在调试时,将断点设置在错误的位置 3.当我有一个很棒的调试想法时 4.偶然间看到自己多年前写的代码 5.当我第一次启动我的单元测试时 ...
Git 天天用 但是 Git 原理你了解吗?
Git 原理 做技术一定要知其然知其所以然,意思就是:知道它是这样的,更知道它为什么是这样的。我主要通过4块内容来简单介绍 Git 是原理是什么样的。这4块内容如下: Git 存储目录结构介绍 Git 是如何存储的 Git 的对象 Git引用 当然 Git 原理不仅仅包含这些,想要更深入了解请查看官方教程 https://git-scm.com/book/zh/v2/。 本文内容是我在 Git...
为什么面向对象糟透了?
又是周末,编程语言“三巨头”Java, Lisp 和C语言在Hello World咖啡馆聚会。服务员送来咖啡的同时还带来了一张今天的报纸, 三人寒暄了几句, C语言翻开了...
Java 每日算法,三个线程按顺序打印
关于多线程的基础知识,可点击下面链接进行学习。 JAVA\Android 多线程实现方式及并发与同步 题目1 启动3个线程A、B、C,使A打印0,然后B打印1,然后C打印2,A打印3,B打印4,C打印5,依次类推。 public class PrintSequenceThread implements Runnable { private static final Ob...
分享靠写代码赚钱的一些门路
作者 mezod,译者 josephchang10如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。今天给大家分享一个精彩...
对计算机专业来说学历真的重要吗?
我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...
技术人员要拿百万年薪,必须要经历这9个段位
很多人都问,技术人员如何成长,每个阶段又是怎样的,如何才能走出当前的迷茫,实现自我的突破。所以我结合我自己10多年的从业经验,总结了技术人员成长的9个段位,希望对大家的职...
8000字干货:那些很厉害的人是怎么构建知识体系的
本文约8000字,正常阅读需要15~20分钟。读完本文可以获得如下收益: 分辨知识和知识体系的差别 理解如何用八大问发现知识的连接点; 掌握致用类知识体系的构建方法; 能够应用甜蜜区模型找到特定领域来构建知识体系。 1. 知识体系?有必要吗? 小张准备通过跑步锻炼身体,可因为之前听说过小腿变粗、膝盖受伤、猝死等等与跑步有关的意外状况,有点担心自己会掉进各种坑里,就在微信上问朋友圈一直晒跑步...
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件
文章目录前言一、nginx简介1. 什么是 nginx 和可以做什么事情2.Nginx 作为 web 服务器3. 正向代理4. 反向代理5. 动静分离6.动静分离二、Nginx 的安装三、 Nginx 的常用命令和配置文件四、 Nginx 配置实例 1 反向代理五、 Nginx 配置实例 2 负载均衡六、 Nginx 配置实例 3 动静分离七、 Nginx 的高可用集群 前言 一、nginx简介...
500行代码,教你用python写个微信飞机大战
这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手。 帮助蹲厕族、YP族、饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右手有节奏有韵律的朝着同一个方向来回移动起来! 这是史诗级的发明,是浓墨重彩的一笔,是…… 在一阵抽搐后,我结束了游戏,瞬时觉得一切都索然无味,正在我进入贤者模式时,突然想到,如果我可以让更多人已不同的方式体会到这种美轮美奂的感觉岂不美哉? 所以我打开电脑,创建了一个 `plan_game.py`……
2019诺贝尔经济学奖得主:贫穷的本质是什么?
2019年诺贝尔经济学奖,颁给了来自麻省理工学院的 阿巴希·巴纳吉(Abhijit Vinayak Banerjee)、艾丝特·杜芙若(Esther Duflo)夫妇和哈...
相关热词 c#俄罗斯方块源码 c# linq原理 c# 装箱有什么用 c#集合 复制 c# 一个字符串分组 c++和c#哪个就业率高 c# 批量动态创建控件 c# 模块和程序集的区别 c# gmap 截图 c# 验证码图片生成类