精华内容
下载资源
问答
  • 便携式信息终端设备,显示屏幕滚动方法,记录介质和计算机设备.zip
  •  LED 显示屏是上世纪80 年代后期在全球迅速发展起来的新型信息传播媒体, 是集电子技术、光电子技术、计算机技术、信息处理技术于一体的大型显示系统。它以其色彩鲜艳、动态范围广、亮度高、寿命长、工作性能稳定...
  •  LED 显示屏是上世纪80 年代后期在迅速发展起来的新型信息传播媒体, 是集电子技术、光电子技术、计算机技术、信息处理技术于一体的大型显示系统。它以其色彩鲜艳、动态范围广、亮度高、寿命长、工作性能稳定而...
  • 绍一种应用广泛的LED 大屏幕异步控制器的设计方案。该系统采用高性能32 位ARM 处理器为其控制核心, 并且基于uc/OS- II 进行软件设计。可实现单屏幕多窗口任意位置的显示, 使得屏幕显示变得丰富灵活。
  • LED显示屏是集电子技术、光电子技术、计算机技术、信息处理技术于一体的大型显示系统。...实验表明按照本系统的设计出的电路简单,控制方便,屏幕显示稳定,效果佳,是现代LED 电子屏的一种很好的解决方案
  • 可实现单屏幕多窗口任意位置的显示, 使得屏幕显示变得丰富灵活。  关键词:LED 大屏幕; 多窗口显示; ARM 处理器; 异步控制器  1 引言  以往的LED 异步控制器只能把一个屏幕作为一个完整的区域来进行显示, ...
  • DLP技术是投影显示领域划时代的革命,它以DMD(Digital Micromirror Device)数字反射器作为光阀成像器件,采用数字光处理技术调制视频信号,驱动DMD光路系统,通过投影透镜获取大屏幕图像。  什么是DLP?如何...
  • 能满足图形曲线和汉字显示的要求,而点阵式LCD不仅可以显示字符、数字,还可以显示各种图形、曲线及汉字,并且可以实现屏幕上下左右滚动动画功能,分区开窗口、反转、闪烁等功能,用途十分广泛,为了简化液晶 显示...
  • CPE 1040-计算机工程概论 作业:通过设计微型“屏幕... 确保可以控制显示哪一个。 将它们包装在函数中是个好主意。 奖励:为micro:bit编写一个Screensaver类。 “屏幕保护程序”应超时,“屏幕”应为空白。 2.2控制
  •  随着计算机和半导体技术的发展,LED大屏幕显示系统成为集计算机控制、视频、光电子、电子、通信、数字图像处理技术为一体的显示设备。目前LED大屏幕显示器向更高亮度、更高耐气候性、更高的发光均匀性、更大屏幕...
  •  在LED大屏幕显示系统对数据输出速度的要求日益提高的背景下,当前对控制设备进行改造的过程中,首选的办法是更换更高速率的处理器,而对硬件电路的挖潜往往容易被忽视。  在实践运用中,建议应先考虑在
  • 由于液晶显示器的光源利用率不足10%,降低亮度并能有效地节省电力,迫不得已的办法是尽可能减少显示屏的工作时间,或者是采用尽可能小的显示屏,结果使观赏舒适性降低,导致PMP的实用价值大打折扣。 理想的适合于...
  • 目前往往存在着微型处理器处理能力有余而端口资源不足的现象,本文对硬件电路并行接口中使用串行传输模式的实现机制进行分析,通过8031控制大屏幕实例验证了在处理器并行接口中传输串行数据的基本方法,并通过硬件...
  • 传统的异步LED大屏幕显示技术以简单的8bit或16bit单片控制器为核心,其运算速度,内存容量,存储空间和通讯方式等方面存在着很大的局限性,很难实现高难度图文动态特技显示和灰度显示等在信息容量和处理速度上要求...
  • 屏幕是1602文本液晶屏,控制器是可信赖的旧Bluepill。 要运行这个小程序,您必须使用Roger Clarks库。 蓝丸的Atleast。 与stm32duino不同,他的Arduino_STM32可以足够快地执行ADC。 这是他图书馆的链接。
  • 话说技巧这个词也是我自己发明的,因为drawable这个东西相信大家天天都在使用,每个人都再熟悉不过了,之所以叫技巧就是对于这个我们再熟悉不过的技术,可能还有一些你所知道的细节,那今天我们就来一起探究...

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/50727753
    好像有挺久时间没更新博客了,最近我为了准备下一个系列的博客,也是花了很长的时间研读源码。很遗憾的是,下一个系列的博客我可能还要再过一段时间才能写出来,那么为了不至于让大家等太久,今天就给大家更新一篇单篇的文章,讲一讲Android drawable方面的微技巧。


    话说微技巧这个词也是我自己发明的,因为drawable这个东西相信大家天天都在使用,每个人都再熟悉不过了,之所以叫微技巧就是对于这个我们再熟悉不过的技术,可能还有一些你所不知道的细节,那今天我们就来一起探究一下这些微小的细节吧。

    大家都知道,在Android项目当中,drawable文件夹都是用来放置图片资源的,不管是jpg、png、还是9.png,都可以放在这里。除此之外,还有像selector这样的xml文件也是可以放在drawable文件夹下面的。

    但是如果你现在使用Android Studio来新建一个项目,你会发现有如下的目录结构:

    嗯?怎么会有这么多mipmap开头的文件夹,而且它们的命名规则和drawable文件夹很相似,也是hdpi、mdpi、xhdpi等等,并且里面还真是放的图片,难道Android项目中放置图片的位置已经改了?

    对于刚刚从Eclipse转向Android Studio的开发者们可能会对mipmap文件夹感到陌生,其实不用担心,我们平时的编程习惯并不需要发生任何改变,因为mipmap文件夹只是用来放置应用程序的icon的,仅此而已。那么在此之前,我们都是把应用程序的icon图标和普通的图片资源一起放到drawable文件夹下的,这样看上去就会比较杂乱,有的时候想从一堆的图片资源里面找icon半天也找不到,而文件一多也就容易出现漏放的情况,但恰恰Android是极度建议我们在每一种分辨率的文件夹下面都放一个相应尺寸的icon的,因此将它们独立出来专门放到mimap文件夹当中就很好地解决了这个问题。

    另外,将icon放置在mipmap文件夹还可以让我们程序的launcher图标自动拥有跨设备密度展示的能力,比如说一台屏幕密度是xxhdpi的设备可以自动加载mipmap-xxxhdpi下的icon来作为应用程序的launcher图标,这样图标看上去就会更加细腻。

    关于建议使用mipmap的原文可以参阅这篇文章:Getting Your Apps Ready for Nexus 6 and Nexus 9, 当然你还是要科学上网的。

    除此之外,对于每种密度下的icon应该设计成什么尺寸其实Android也是给出了最佳建议,icon的尺寸最好不要随意设计,因为过低的分辨率会造成图标模糊,而过高的分辨率只会徒增APK大小。建议尺寸如下表所示:

    密度建议尺寸
    mipmap-mdpi48 * 48
    mipmap-hdpi72 * 72
    mipmap-xhdpi96 * 96
    mipmap-xxhdpi144 * 144
    mipmap-xxxhdpi192 * 192

    然后我们引用mipmap的方式和之前引用drawable的方式是完全一致的,在资源中就使用@mipmap/res_id,在代码就使用R.mipmap.res_id。比如AndroidManifest.xml中就是这样引用ic_launcher图标的:

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

    好的,关于mimap的内容就讲这么多,它并不是本篇文章的重点,接下来我们来真真正正看一些drawable的微技巧。


    首先我准备了一张270*480像素的图片:


    将图片命名为android_logo.png,然后把它放在drawable-xxhdpi文件夹下面。为什么要放在这个文件夹下呢?是因为我的手机屏幕的密度就是xxhdpi的。那么怎么才能知道自己手机屏幕的密度呢?你可以使用如下方法先获取到屏幕的dpi值:

    float xdpi = getResources().getDisplayMetrics().xdpi;
    float ydpi = getResources().getDisplayMetrics().ydpi;

    其中xdpi代表屏幕宽度的dpi值,ydpi代表屏幕高度的dpi值,通常这两个值都是近乎相等或者极其接近的,在我的手机上这两个值都约等于403。那么403又代表着什么意思呢?我们直接参考下面这个表格就知道了:

    dpi范围密度
    0dpi ~ 120dpildpi
    120dpi ~ 160dpimdpi
    160dpi ~ 240dpihdpi
    240dpi ~ 320dpixhdpi
    320dpi ~ 480dpixxhdpi
    480dpi ~ 640dpixxxhdpi

    从表中可以看出,403dpi是处于320dpi到480dpi之间的,因此属于xxhdpi的范围。

    图片放好了之后,下面我在布局文件中引用这张图片,如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       >
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/android_logo"
            />
    
    </LinearLayout>

    在ImageView控件中指定加载android_logo这张图,并把ImageView控件的宽高都设置成wrap_content,这样图片有多大,我们的控件就会有多大。

    现在运行一下程序,效果如下所示:

    由于我的手机分辨率是1080*1920像素的,而这张图片的分辨率是270*480像素的,刚好是手机分辨率的四分之一,因此从上图中也可以看出,android_logo图片的宽和高大概都占据了屏幕宽高的四分之一左右,大小基本是比较精准的。

    到目前为止一切都挺顺利的,不是吗?下面我们尝试做点改变,将android_logo.png这张图移动到drawable-xhdpi文件夹下,注意不是复制一份到drawable-xhdpi文件夹下,而是将图片移动到drawable-xhdpi文件夹下,然后重新运行一下程序,效果如下图所示:

    嗯?怎么感觉图片好像变大了一点,是错觉吗?

    那么我们再将这张图移动到drawable-mdpi文件夹下试试,重新运行程序,效果如下图所示:

    这次肯定不是错觉了,这实在是太明显了,图片被放大了!

    那么为什么好端端的一张图片会被自动放大呢?而且这放大的比例是不是有点太过份了。其实不然,Android所做的这些缩放操作都是有它严格的规定和算法的。可能有不少做了很多年Android的朋友都没去留意过这些缩放的规则,因为这些细节太微小了,那么本篇的微技巧探索里面,我们就来把这些细节理理清楚。

    首先解释一下图片为什么会被放大,当我们使用资源id来去引用一张图片时,Android会使用一些规则来去帮我们匹配最适合的图片。什么叫最适合的图片?比如我的手机屏幕密度是xxhdpi,那么drawable-xxhdpi文件夹下的图片就是最适合的图片。因此,当我引用android_logo这张图时,如果drawable-xxhdpi文件夹下有这张图就会优先被使用,在这种情况下,图片是不会被缩放的。但是,如果drawable-xxhdpi文件夹下没有这张图时, 系统就会自动去其它文件夹下找这张图了,优先会去更高密度的文件夹下找这张图片,我们当前的场景就是drawable-xxxhdpi文件夹,然后发现这里也没有android_logo这张图,接下来会尝试再找更高密度的文件夹,发现没有更高密度的了,这个时候会去drawable-nodpi文件夹找这张图,发现也没有,那么就会去更低密度的文件夹下面找,依次是drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。
    总体匹配规则就是这样,那么比如说现在终于在drawable-mdpi文件夹下面找到android_logo这张图了,但是系统会认为你这张图是专门为低密度的设备所设计的,如果直接将这张图在当前的高密度设备上使用就有可能会出现像素过低的情况,于是系统自动帮我们做了这样一个放大操作。

    那么同样的道理,如果系统是在drawable-xxxhdpi文件夹下面找到这张图的话,它会认为这张图是为更高密度的设备所设计的,如果直接将这张图在当前设备上使用就有可能会出现像素过高的情况,于是会自动帮我们做一个缩小的操作。所以,我们可以尝试将android_logo这张图移动到drawable-xxxhdpi文件夹下面将会得到这样的结果:

    可以看到,现在图片的宽和高都达到不手机屏幕的四分之一,说明图片确实是被缩小了。

    另外,刚才在介绍规则的时候提到了一个drawable-nodpi文件夹,这个文件夹是一个密度无关的文件夹,放在这里的图片系统就不会对它进行自动缩放,原图片是多大就会实际展示多大。但是要注意一个加载的顺序,drawable-nodpi文件夹是在匹配密度文件夹和更高密度文件夹都找不到的情况下才会去这里查找图片的,因此放在drawable-nodpi文件夹里的图片通常情况下不建议再放到别的文件夹里面。

    图片被放大的原因现在我们已经搞清楚了,那么接下来还有一个问题,就是放大的倍数是怎么确定的呢?很遗憾,我没有找到相关的文档记载,但是我自己总结出了一个规律,这里跟大家分享一下。

    还是看一下刚才的 dpi范围-密度 表格:

    dpi范围密度
    0dpi ~ 120dpildpi
    120dpi ~ 160dpimdpi
    160dpi ~ 240dpihdpi
    240dpi ~ 320dpixhdpi
    320dpi ~ 480dpixxhdpi
    480dpi ~ 640dpixxxhdpi

    可以看到,每一种密度的dpi范围都有一个最大值,这个最大值之间的比例就是图片会被系统自动放大的比例。
    口说无凭,下面我们来通过实例验证一下,修改布局文件中的代码,如下所示:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       >
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/android_logo"
            />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取图片宽高"
            android:onClick="buttonClick"
            />
    
    </LinearLayout>

    可以看到,我们添加了一个按钮,并给按钮注册了一个点击事件。然后在MainActivity中处理这个点击事件:

    public class MainActivity extends AppCompatActivity {
    
        ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = (ImageView) findViewById(R.id.image);
        }
    
    
        public void buttonClick(View view) {
            Toast.makeText(this, "图片宽度:" + imageView.getWidth(), Toast.LENGTH_SHORT).show();
            Toast.makeText(this, "图片高度:" + imageView.getHeight(), Toast.LENGTH_SHORT).show();
        }
    }

    这里在点击事件中分别获取图片的宽和高并使用Toast提示出来。代码修改这么多就可以了,然后将图片移动到drawable-mdpi文件夹下。

    下面我们来开始分析,mdpi密度的最高dpi值是160,而xxhdpi密度的最高dpi值是480,因此是一个3倍的关系,那么我们就可以猜测,放到drawable-mdpi文件夹下的图片在xxhdpi密度的设备上显示会被放大3倍。对应到android_logo这张图,原始像素是270*480,放大3倍之后就应该是810*1440像素。下面运行程序,效果如下图所示:

    验证通过。我们再来试验一次,将图片移动到drawable-xxxhdpi目录下。xxxhdpi密度的最高dpi值是640,480是它的0.75倍,那么我们就可以猜测,放到drawable-xxxdpi文件夹下的图片在xxhdpi密度的设备上显示会被缩小至0.75倍。270*480的0.75倍应该是202.5*360,由于像素不支持小数点,那么四舍五入就应该是203*360像素。重新运行程序,效果如下图所示:

    再次验证通过。如果你有兴趣的话可以使用其它几种dpi的drawable文件夹来试一试,应该都是适配这套缩放规则的。这样我们就把图片为什么会被缩放,以及具体的缩放倍数都搞明白了,drawable相关的细节你已经探究的非常细微了。

    不过本篇文章到这里还没结束,下面我准备讲一讲我们在实际开发当中会遇到的场景。根据Android的开发建议,我们在准备图片资源时尽量应该给每种密度的设备都准备一套,这样程序的适配性就可以达到最好。但实际情况是,公司的UI们通常就只会给一套图片资源,想让他们针对每种密度的设备都设计一套图片资源,并且还是按照我们上面讲的缩放比例规则来设计,就有点想得太开心了。没错,这个就是现实情况,那么在这种情况下,我们应该将仅有的这一套图片资源放在哪个密度的文件夹下呢?

    可以这样来分析,根据我们刚才所学的内容,如果将一张图片放在低密度文件夹下,那么在高密度设备上显示图片时就会被自动放大,而如果将一张图片放在高密度文件夹下,那么在低密度设备上显示图片时就会被自动缩小。那我们可以通过成本的方式来评估一下,一张原图片被缩小了之后显示其实并没有什么副作用,但是一张原图片被放大了之后显示就意味着要占用更多的内存了。因为图片被放大了,像素点也就变多了,而每个像素点都是要占用内存的。

    我们仍然可以通过例子来直观地体会一下,首先将android_logo.png图片移动到drawable-xxhdpi目录下,运行程序后我们通过Android Monitor来观察程序内存使用情况:

    可以看到,程序所占用的内存大概稳定在19.45M左右。然后将android_logo.png图片移动到drawable-mdpi目录下,重新运行程序,结果如下图所示:

    现在涨到23.40M了,占用内存明显增加了。如果你将图片移动到drawable-ldpi目录下,你会发现占用内存会更高。

    通过这个例子同时也验证了一个问题,我相信有不少比较有经验的Android程序员可能都遇到过这个情况,就是当你的项目变得越来越大,有的时候加载一张drawable-hdpi下的图片,程序就直接OOM崩掉了,但如果将这张图放到drawable-xhdpi或drawable-xxhdpi下就不会崩掉,其实就是这个道理。

    那么经过上面一系列的分析,答案自然也就出来了,图片资源应该尽量放在高密度文件夹下,这样可以节省图片的内存开支,而UI在设计图片的时候也应该尽量面向高密度屏幕的设备来进行设计。就目前来讲,最佳放置图片资源的文件夹就是drawable-xxhdpi。那么有的朋友可能会问了,不是还有更高密度的drawable-xxxhdpi吗?干吗不放在这里?这是因为,市面上480dpi到640dpi的设备实在是太少了,如果针对这种级别的屏幕密度来设计图片,图片在不缩放的情况下本身就已经很大了,基本也起不到节省内存开支的作用了。


    好的,关于drawable微技巧方面的探索我们就讲到这里,本篇文章中也是集合了不少我平时的工作经验总结,以及通过做试验所得出的一些结论,相信还是可以给大家带来不少帮助的。后面我会抓紧时间继续准备新系列的内容,敬请期待。

    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

            

    展开全文
  • DLP大屏幕如何工作

    2020-08-25 18:17:46
    DLP是英文Digital ...DLP技术是投影显示领域划时代的革命,它以DMD(Digital Micromirror Device)数字反射器作为光阀成像器件,采用数字光处理技术调制视频信号,驱动DMD光路系统,通过投影透镜获取大屏幕图像。
  • 私人订制自己的屏幕截图工具(二)创建项目、注册热键、显示截图主窗口 实现热键功能 这里需要使用WindowsAPI 注册热键:RegisterHotKey 该函数定义一个系统范围的热键。函数原型:BOOL RegisterHotKey(HWND hWnd,...

    本实例全部文章目录


    开发环境

    操作系统:Windows Server 2008 R2

    集成开发环境(IDE):Microsoft Visual Studio 2010

    开发语言:c#

    创建项目

    文件》新建》项目


    .NET Framework可以选择2.0版本,也可以选择4.0版本;

    项目类型选择:Windows窗体应用程序

    输入项目名称,确定


    项目创建成功,如下图:


    修改主窗体属性

    修改窗体的“FormBorderStyle”属性为“none”,实现一个没有边框的窗体


    修改后窗口设计器中显示如下:


    依次按下图修改其它属性,属性值黑体加粗的是修改过的


    属性说明:

    ShowIcon=False,不显示窗体的图标;

    ShowInTaskbar=False,使窗体不在Windows任务栏中出现;

    SizeGripStyle=Hide,禁用拖动窗体右下角可以改变大小的功能;

    WindowsState=Minimized,窗口启动后最小化;

    设置完这些属性后,编译,运行,程序是在运行状态,但是却看不到程序的窗口;

    实现热键功能

    这里需要使用WindowsAPI

    注册热键:RegisterHotKey

    该函数定义一个系统范围的热键函数原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk);

    取消热键注册:UnregisterHotKey

    该函数释放调用线程先前登记的热键。

    获取热键ID:GlobalAddAtom

    只适用于桌面应用程序。
    向全局原子表添加一个字符串,并返回这个字符串的唯一标识符(原子ATOM)。

    API及局部变量定义:

            /// <summary>
            /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符(原子ATOM)。
            /// </summary>
            /// <param name="lpString">自己设定的一个字符串</param>
            /// <returns></returns>
            [System.Runtime.InteropServices.DllImport("Kernel32.dll")]
            public static extern Int32 GlobalAddAtom(string lpString);
    
            /// <summary>
            /// 注册热键
            /// </summary>
            /// <param name="hWnd"></param>
            /// <param name="id"></param>
            /// <param name="fsModifiers"></param>
            /// <param name="vk"></param>
            /// <returns></returns>
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
    
            /// <summary>
            /// 取消热键注册
            /// </summary>
            /// <param name="hWnd"></param>
            /// <param name="id"></param>
            /// <returns></returns>
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            /// <summary>
            /// 热键ID
            /// </summary>
            public int hotKeyId = 100;
    
            /// <summary>
            /// 热键模式:0=Ctrl + Alt + A, 1=Ctrl + Shift + A
            /// </summary>
            public int HotKeyMode = 1;
    
            /// <summary>
            /// 控制键的类型
            /// </summary>
            public enum KeyModifiers : uint
            {
                None = 0,
                Alt = 1,
                Control = 2,
                Shift = 4,
                Windows = 8
            }
    
            /// <summary>
            /// 用于保存截取的整个屏幕的图片
            /// </summary>
            protected Bitmap screenImage;

    注册热键:

            private void Form1_Load(object sender, EventArgs e)
            {
                //隐藏窗口
                this.Hide();
    
                //注册快捷键
                //注:HotKeyId的合法取之范围是0x0000到0xBFFF之间,GlobalAddAtom函数得到的值在0xC000到0xFFFF之间,所以减掉0xC000来满足调用要求。
                this.hotKeyId = GlobalAddAtom("Screenshot") - 0xC000;
                if (this.hotKeyId == 0)
                {
                    //如果获取失败,设定一个默认值;
                    this.hotKeyId = 0xBFFE; 
                }
    
                if (this.HotKeyMode == 0)
                {
                    RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Alt, Keys.A);
                }
                else
                {
                    RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Shift, Keys.A);
                }
            }

    热键响应函数:

            /// <summary>
            /// 处理快捷键事件
            /// </summary>
            /// <param name="m"></param>
            protected override void WndProc(ref Message m)
            {
                //if (m.Msg == 0x0014)
                //{
                //    return; // 禁掉清除背景消息
                //}
                const int WM_HOTKEY = 0x0312;
                switch (m.Msg)
                {
                    case WM_HOTKEY:
                        ShowForm();
                        break;
                    default:
                        break;
                }
                base.WndProc(ref m);
            }

    截图窗口实现原理

    截图窗口实际是一个没有边框,没有菜单,没有工具栏的一个全屏顶层窗口。

    当按下热键时,程序首先获取整个屏幕的图片,保存到“screenImage”变量中;然后添加遮罩层,将其设置为窗体的背景图,将窗口大小设置为主屏幕的大小,显示窗口;让人感觉是在桌面上加一个半透明的遮罩层一样。

    代码如下:

            /// <summary>
            /// 如果窗口为可见状态,则隐藏窗口;
            /// 否则则显示窗口
            /// </summary>
            protected void ShowForm()
            {
                if (this.Visible)
                {
                    this.Hide();
                }
                else
                {
                    Bitmap bkImage = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
                    Graphics g = Graphics.FromImage(bkImage);
                    g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size, CopyPixelOperation.SourceCopy);
                    screenImage = (Bitmap)bkImage.Clone();
                    g.FillRectangle(new SolidBrush(Color.FromArgb(64, Color.Gray)), Screen.PrimaryScreen.Bounds);
                    this.BackgroundImage = bkImage;
    
                    this.ShowInTaskbar = false;
                    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
                    this.Width = Screen.PrimaryScreen.Bounds.Width;
                    this.Height = Screen.PrimaryScreen.Bounds.Height;
                    this.Location = Screen.PrimaryScreen.Bounds.Location;
    
                    this.WindowState = FormWindowState.Maximized;
                    this.Show();
                }
            }

    取消热键注册

    关闭窗口时,要取消热键注册,代码如下:

            /// <summary>
            /// 当窗口正在关闭时进行验证
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (e.CloseReason == CloseReason.ApplicationExitCall)
                {
                    e.Cancel = false;
                    UnregisterHotKey(this.Handle, hotKeyId);
                }
                else
                {
                    this.Hide();
                    e.Cancel = true;
                }
            }

    到这里,热键注册,截图窗口的显示等功能已经基本完成。

    注意:测试本代码时最好在窗体上添加一个按钮,用于关闭或隐藏截图窗口;因为截图窗口是全屏的,不能响应ESC键,所以只能通过任务管理器来结束进程退出。调试时最好是在窗体上添加一个Label控件来显示需要的变量信息,因为截图窗口是顶层的全屏窗口,断点被命中时根本没办法操作VS。

    展开全文
  • 设置树莓派屏幕常亮,禁止树莓派屏幕休眠

    千次阅读 多人点赞 2020-07-19 20:35:33
    2、 Raspbian系统使用的是lightdm桌面显示管理器,可以设置xservice桌面交互显示来达到屏幕常亮的目的。 3、修改桌面配置文件lightdm.conf sudo nano /etc/lightdm/lightdm.conf 找到[Seat:*]这一

    设置树莓派屏幕常亮,禁止树莓派屏幕休眠

    树莓派是微型电脑,系统自带休眠保护功能,但是有人可能会处理一些事务,想树莓派屏幕常亮,保证树莓派一直都处于活动状态,今天分享如何让树莓派屏幕常亮,禁止休眠的解决方案。

    1、 系统:raspbian系统。

    2、 Raspbian系统使用的是lightdm桌面显示管理器,可以设置xservice桌面交互显示来达到屏幕常亮的目的。

    3、修改桌面配置文件lightdm.conf

    sudo nano /etc/lightdm/lightdm.conf
    

    找到[Seat:*]这一项,在下面的‘#xserver-command=X’删除前面的注释符#,修改为以下

    xserver-command=X -s 0-dpms
    

    在这里插入图片描述

    其中,-s 参数:设置屏幕保护不启动,0 数字零,-dpms 参数:关闭电源节能管理。

    保存退出:Ctrl+X,按Y 再按回车。

    4、重启系统。

    sudo reboot
    
    展开全文
  •  随着计算机和半导体技术的发展,LED大屏幕显示系统成为集计算机控制、视频、光电子、电子、通信、数字图像处理技术为一体的显示设备。目前LED大屏幕显示器向更高亮度、更高耐气候性、更高的发光均匀性、更大屏幕...
  • Android状态栏技巧,动态控制状态栏显示和隐藏

    万次阅读 多人点赞 2017-04-18 15:31:29
    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的技巧讲解。其实说到沉浸式状态栏这个名字我也是感到很无奈,真知道这种叫法是谁先发起...

    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。

    其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起的。因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法。而有些人在没有完全了解清楚沉浸模式到底是什么东西的情况下,就张冠李戴地认为一些系统提供的状态栏操作就是沉浸式的,并且还起了一个沉浸式状态栏的名字。

    比如之前就有一个QQ群友问过我,像饿了么这样的沉浸式状态栏效果该如何实现?

    这里写图片描述

    这个效果其实就是让背景图片可以利用系统状态栏的空间,从而能够让背景图和状态栏融为一体。

    本篇文章当中我会教大家如何实现这样的效果,但这个真的不叫沉浸式状态栏。因此,这算是一篇技术+普及的文章吧,讲技术的同时也纠正一下大家之前错误的叫法。

    什么是沉浸式?

    先来分析一下叫错的原因吧,之所以很多人会叫错,是因为根本就不了解沉浸式是什么意思,然后就人云亦云跟着叫了。那么沉浸式到底是什么意思呢?

    根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉。

    比如说现在大热的VR就是主打的沉浸式体验。

    那么对应到Android操作系统上面,怎样才算是沉浸式体验呢?这个可能在大多数情况下都是用不到的,不过在玩游戏或者看电影的时候就非常重要了。因为游戏或者影视类的应用都希望能让用户完全沉浸在其中,享受它们提供的娱乐内容,但如果这个时候在屏幕的上方还显示一个系统状态栏的话,可能就会让用户分分钟产生跳戏的感觉。

    那么我们来看一下比较好的游戏都是怎么实现的,比如说海岛奇兵:

    这里写图片描述

    海岛奇兵的这种模式就是典型的沉浸式模式,它的整个屏幕中显示都是游戏的内容,没有状态栏也没有导航栏,用户玩游戏的时候就可以完全沉浸在游戏当中,而不会被一些系统的界面元素所打扰。

    然后我们再来看一下爱奇艺的实现:

    这里写图片描述
    同样也是类似的,爱奇艺将整个屏幕作为影视的展示区,用户在看电影的时候眼中就只会有电影的内容,这样就不会被其他一些无关的东西所分心。

    这才是沉浸式模式的真正含义,而所谓的什么沉浸式状态栏纯粹就是在瞎叫,完全都没搞懂“沉浸式” 这三个字是什么意思。

    不过虽然听上去好像是很高大上的沉浸式效果,实际看上去貌似就是将内容全屏化了而已嘛。没错,Android沉浸式模式的本质就是全屏化,不过我们今天的内容并不仅限于此,因为还要实现饿了么那样的状态栏效果。那么下面我们就开始来一步步学习吧。

    隐藏状态栏
    这里写图片描述

    可以看到,有状态栏、ActionBar、导航栏等。而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分。

    比如说我现在新建了一个空项目,然后修改布局文件中的代码,在里面加入一个ImageView,如下所示:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/bg"
            android:scaleType="centerCrop" />
    
    </RelativeLayout>
    

    这里将ImageView的宽和高都设置成match_parent,让图片充满屏幕。现在运行一下程序,效果如下图所示。

    这里写图片描述
    如果你将图片理解成游戏或者电影界面的话,那这个体验离沉浸式就差得太远了,至少状态栏和ActionBar得要隐藏起来了吧?没关系,我们一步步进行优化,并且在优化中学习。

    隐藏状态栏和ActionBar的方式在4.1系统之上和4.1系统之下还是不一样的,这里我就不准备考虑4.1系统之下的兼容性了,因为过于老的系统根本就没有提供沉浸式体验的支持。

    修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(option);
            ActionBar actionBar = getSupportActionBar();
            actionBar.hide();
        }
    }
    

    这里先调用getWindow().getDecorView()方法获取到了当前界面的DecorView,然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏。另外,根据Android的设计建议,ActionBar是不应该独立于状态栏而单独显示的,因此状态栏如果隐藏了,我们同时也需要调用ActionBar的hide()方法将ActionBar也进行隐藏。

    现在重新运行一下程序,效果如下图所示。

    这里写图片描述
    这样看上去就有点沉浸式效果的模样了。

    虽说这才是正统的沉浸式含义,但有些朋友可能想实现的就是饿了么那样的状态栏效果,而不是直接把整个系统状态栏给隐藏掉,那么又该如何实现呢?

    其实也很简单,只需要借助另外一种UI Flag就可以了,如下所示:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
    

    首先需要注意,饿了么这样的效果是只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。

    接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。

    现在重新运行一下代码,效果如下图所示。

    这里写图片描述
    可以看到,类似于饿了么的状态栏效果就成功实现了。

    再声明一次,这种效果不叫沉浸式状态栏,也完全没有沉浸式状态栏这种说法,我们估且可以把它叫做透明状态栏效果吧。

    隐藏导航栏
    现在我们已经成功实现隐藏状态栏的效果了,不过屏幕下方的导航栏还比较刺眼,接下来我们就学习一下如何将导航栏也进行隐藏。

    其实实现的原理都是一样的,隐藏导航栏也就是使用了不同的UI Flag而已,修改MainActivity中的代码,如下所示:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    View decorView = getWindow().getDecorView();
    int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(option);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
    

    这里我们同时使用了SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN,这样就可以将状态栏和导航栏同时隐藏了。现在重新运行一下程序,效果如图所示。
    这里写图片描述

    这次看上去好像终于是完全全屏化了,但其实上这离真正的沉浸式模式还差得比较远,因为在这种模式下,我们触摸屏幕的任意位置都会退出全屏。
    这里写图片描述
    这显然不是我们想要的效果,因此这种模式的使用场景比较有限。

    除了隐藏导航栏之外,我们同样也可以实现和刚才透明状态栏类似的效果,制作一个透明导航栏:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
    

    这里使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用系统导航栏的空间,然后又调用了setNavigationBarColor()方法将导航栏设置成透明色。现在重新运行一下程序,效果如下图所示。
    这里写图片描述

    真正的沉浸式模式
    虽说沉浸式导航栏这个东西是被很多人误叫的一种称呼,但沉浸式模式的确是存在的。那么我们如何才能实现像海岛奇兵以及爱奇艺那样的沉浸式模式呢?

    首先你应该确定自己是否真的需要这个功能,因为除了像游戏或者视频软件这类特殊的应用,大多数的应用程序都是用不到沉浸式模式的。

    当你确定要使用沉浸式模式,那么只需要重写Activity的onWindowFocusChanged()方法,然后加入如下逻辑即可:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            if (hasFocus && Build.VERSION.SDK_INT >= 19) {
                View decorView = getWindow().getDecorView();
                decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            }
        }
    
    }
    

    沉浸式模式的UI Flag就这些,也没什么好解释的,如果你需要实现沉浸式模式,直接将上面的代码复制过去就行了。需要注意的是,只有在Android 4.4及以上系统才支持沉浸式模式,因此这里也是加入了if判断。

    另外,为了让我们的界面看上去更像是游戏,这里我将MainActivity设置成了横屏模式:

    <activity android:name=".MainActivity" 
              android:screenOrientation="landscape">
        ...
    </activity>
    

    这样我们就实现类似于海岛奇兵和爱奇艺的沉浸式模式效果了,如下图所示。
    这里写图片描述
    可以看到,界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,只需要在屏幕顶部向下拉,或者在屏幕右侧向左拉,状态栏和导航栏就会显示出来,此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,状态栏和导航栏又会自动隐藏起来,重新回到全屏状态。

    这就是最标准的沉浸式模式。

    android 动态控制状态栏显示和隐藏的方法实例

    android想要应用运行时全屏有一种方法是在activity的onCreat方法中加入如下代码:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);并且需要在setContentView()之前,否则无效过。从这么多的苛刻条件可以看出这种方法无法满足动态控制。

    下面的方法可以满足这个需要。调用View的 setSystemUiVisibility()

    方法,其参数如下:

    View.SYSTEM_UI_FLAG_FULLSCREEN, //全屏,状态栏和导航栏不显示
    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION, //隐藏导航栏
    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN, //全屏,状态栏会盖在布局上
    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE,
    View.SYSTEM_UI_FLAG_LOW_PROFILE,
    View.SYSTEM_UI_FLAG_VISIBLE, //显示状态栏和导航栏
    View.SYSTEM_UI_LAYOUT_FLAGS

    Android colorPrimary colorPrimaryDark colorAccent

    这里写图片描述

    Android design theme color

    <style name="AppTheme.NoActionBar">
        <!--状态栏颜色-->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <!--控制各个控件被选中时的颜色-->
        <item name="colorAccent">@color/colorAccent</item>
        <!--页面背景色-->
        <item name="android:windowBackground">@color/windowBackg</item>
        <!--底部导航栏颜色-->
        <item name="android:navigationBarColor">@color/navigationColor</item>
        <!--Appbar背景色-->
        <item name="android:colorPrimary">@color/colorPrimary</item>
        <!--ToolBar上的Title颜色-->
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <!--各个控制控件的默认颜色-->
        <item name="android:colorControlNormal">@color/colorControlNormal</item>
    </style>
    

    这里写图片描述
    Android design theme color 保存在res/values/styles.xml下

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
    </resources>
    

    color rgb值保存在res/values/colors.xml下

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimary">#3F51B5</color>
        <color name="colorPrimaryDark">#000000</color>
        <color name="colorAccent">#ffffff</color>
    </resources>
    

    原创地址:
    http://blog.csdn.net/guolin_blog/article/details/51763825
    https://blog.csdn.net/kangweijian

    之前没有注意, 没有写原创地址, 最近重新看总结过的东西, 发现竟然没有附地址, 现在加上.

    展开全文
  • 废话多说直接入正题 图片能过大 图片命名能含有中文 图片命名也能有空格 图片大小写要区分 ...当我们用编辑器编写用于手机端的自适应单位用的自然是rpx,但是根据不同的手机屏幕大小...
  •  在LED大屏幕显示系统对数据输出速度的要求日益提高的背景下,当前对控制设备进行改造的过程中,的办法是更换更高速率的处理器,而对硬件电路的挖潜往往容易被忽视。  在实践运用中,建议应先考虑在原有
  • 如果触摸可用但显示好,就要换触摸与外保护玻璃。触摸是一张有机膜。 2,明白如果带接口的就在拆机。 3,网上店家的教程里有个小坑。 出错的地方。 1,拆机时出问题,首先拆下了后盖时没出错,这是因为这东西...
  • Android状态栏技巧,带你真正理解沉浸式模式

    万次阅读 多人点赞 2016-08-23 07:32:55
    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的技巧讲解。 其实说到沉浸式状态栏这个名字我也是感到很无奈,真知道这种叫法是谁先...
  • Android件(续)

    千次阅读 2020-07-30 18:41:27
    Android件(续) Google 文档 几年前前写过一篇Android桌面小插件——Widget 重新梳理一下 温故知新 问:开发一个最简单的件总共分几步? 答:总共分4步。 1、创建一个AppWidgetProvider; 2、创建一个件布局...
  • 摘要: 当LED显示器采用8位/16位处理器时,存在运行速度慢、寻址能力弱和功耗大等... 随着计算机和半导体技术的发展,使LED大屏幕显示系统成为集计算机控制、视频、光电子、电子、通信、数字图像处理技术为一体的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,713
精华内容 10,285
关键字:

微信息屏幕不显示