首页 文章 精选 留言 我的

精选列表

搜索[镜像无法拉取],共10000篇文章
优秀的个人博客,低调大师

鼠标像素拾取器的实现(坐标&RGB)

环境:jdk1.2+包: import java.awt.BorderLayout;import java.awt.Color; import java.awt.Font;import java.awt.Point;import java.awt.Robot;import java.awt.Toolkit;import java.awt.datatransfer.Clipboard;import java.awt.datatransfer.StringSelection;import java.awt.datatransfer.Transferable;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Timer;import java.util.TimerTask;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.border.EmptyBorder; 主类:MousePixInfo3(main内实例化) 第一步:设计界面构造函数内渲染jframe过程略.. 第二步:调用标准库: 利用Robot.getPixelColor(x,y)方法得到Color对象; 利用MouseInfo.getPointerInfo().getLocation()得到Point对象; 利用Integer.toHexString(int i)方法将rgb值转成更易读的十六进制; 利用Timer.schedule(TimerTask timerTask)周期刷新像素信息; 第三步:扩展功能: 1.jframe置顶(Jframe.setAlwaysOnTop(true))(非聚焦) 2.esc键退出(System.exit(0)) 3.空格暂停(timer.cancel()) 4.L键将坐标值存入系统剪切板 5.C键将颜色值存入系统剪切板 源码: package test; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Point; import java.awt.Robot; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class MousePixInfo3 extends JFrame { /** * */ private static final long serialVersionUID = 1L; private final JPanel contentPanel = new JPanel(); static JLabel value_x = null; static JLabel value_y = null; static JLabel myPixColorHex = null; static Robot myRobot; static Timer timer = new Timer(); JLabel lblx = new JLabel("X :"); JLabel lbly = new JLabel("Y :"); static boolean isRunning = true; JLabel note1; JLabel note2; /** * Launch the application. */ public static void main(String[] args) { try { myRobot = new Robot(); MousePixInfo3 info_frame = new MousePixInfo3(); info_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); info_frame.setVisible(true); info_frame.setAlwaysOnTop(true); info_frame.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { System.exit(0); } else if (e.getKeyChar() == ' ') { if (isRunning) { timer.cancel(); isRunning = false; } else { run(); isRunning = true; } } else if (e.getKeyChar() == 'l') { setSysClipboardText(value_x.getText() + "," + value_y.getText()); } else if (e.getKeyChar() == 'c') { setSysClipboardText(myPixColorHex.getText()); } } }); run(); } catch (Exception e) { e.printStackTrace(); } } /** * Create the dialog. */ public static void setSysClipboardText(String writeMe) { Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable tText = new StringSelection(writeMe); clip.setContents(tText, null); } public static void run() { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Point point = java.awt.MouseInfo.getPointerInfo().getLocation(); Color myPixColor = myRobot.getPixelColor(point.x, point.y); String r = Integer.toHexString(myPixColor.getRed()); String g = Integer.toHexString(myPixColor.getGreen()); String b = Integer.toHexString(myPixColor.getBlue()); value_x.setText("" + point.x); // 双引号""把int转成string value_y.setText("" + point.y); myPixColorHex.setText("#" + r + g + b); } }, 100, 50);// 设置100ms后开始,每50ms检测一次坐标 } public MousePixInfo3() { timer = new Timer(); setTitle("像素采集神器"); setBounds(100, 100, 317, 192); getContentPane().setLayout(new BorderLayout()); contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); getContentPane().add(contentPanel, BorderLayout.CENTER); contentPanel.setLayout(null); lblx.setFont(new Font("宋体", Font.PLAIN, 15)); lblx.setBounds(22, 27, 66, 31); contentPanel.add(lblx); lbly.setFont(new Font("宋体", Font.PLAIN, 15)); lbly.setBounds(22, 68, 66, 31); contentPanel.add(lbly); value_x = new JLabel("0"); value_x.setForeground(Color.BLUE); value_x.setFont(new Font("宋体", Font.PLAIN, 20)); value_x.setBounds(64, 27, 66, 31); contentPanel.add(value_x); value_y = new JLabel("0"); value_y.setForeground(Color.BLUE); value_y.setFont(new Font("宋体", Font.PLAIN, 20)); value_y.setBounds(64, 68, 66, 31); contentPanel.add(value_y); myPixColorHex = new JLabel("0"); myPixColorHex.setForeground(Color.RED); myPixColorHex.setFont(new Font("宋体", Font.PLAIN, 32)); myPixColorHex.setBounds(142, 48, 128, 31); contentPanel.add(myPixColorHex); note1 = new JLabel("esc退出;Space暂停/继续", JLabel.CENTER); note1.setFont(new Font("幼圆", Font.PLAIN, 16)); getContentPane().add(note1, BorderLayout.SOUTH); note2 = new JLabel("'l'复制location;'c'复制color", JLabel.CENTER); note2.setFont(new Font("幼圆", Font.PLAIN, 16)); getContentPane().add(note2, BorderLayout.NORTH); } }

优秀的个人博客,低调大师

Python网络爬虫之爬取糗事百科案例

项目说明 使用Python写网络爬虫之糗事百科示例 使用工具 Python2.7.X、pycharm 使用方法 在pycharm中创建一个ceshi.py文件,撰写代码,运行代码,查看运行结果 操作原理 1.首先先了解正则表达式的使用方法,见:正则表达式 2.找到糗事百科的主页URL:http://www.qiushibaike.com/hot/page/1 可以看出来,链接中page/后面的数字就是对应的页码,记住这一点为编写程序做准备。 然后,右击查看页面源码: 网页源码分析-图1 网页源码分析-图2 观察发现,每一个段子都用div标记,其中class必为content,我们只需要用正则表达式将其“扣”出来就可以了。 示例代码 代码示例1 代码示例2 运行结果 运行结果 参考来源:http://blog.csdn.net/pleasecallmewhy/article/details/8932310

优秀的个人博客,低调大师

RFID技术取突破,物联网产品或摆脱充电线

曾经创见发表过一篇文章:《从 Nest 烟雾报警器看智能硬件的软肋与出路》,文章的最后指出了智能硬件,又或者是物联网产品目前所存在的最大障碍:它们新奇有余,耐久不足。往往这些产品摆放在家里面之后,没有人会管它们,这个时候电能供应就成为了最大的问题。没有人时不时爬高上低地给各种家具换电池。如果是报警装置,没电了也没人意识到,危险发生时发挥不出应有的作用就更加麻烦了! 然而今天无线射频技术有了新突破,物联网产品终于有可能摆脱对人工充电的依赖了! 物联网时代是一个很宏大的愿景,每一款产品都能通过网络进行智能连接。从你的割草机到你的窗帘再到你的办公室写字椅,每一个家具或者电器都能够相互彼此实现通讯。这听起来固然很美好,但是想要驶向这样一个未来,你必须彻底地改变物联网产品电力的驱动方式。 而如今,来自华盛顿大学的研究人员给我们带来了最新的解决方案:通过射频设别技术(RFID),得到一种摆脱电池依赖的计算机。 大家一般所能见到的无线射频技术(RFID),一般都应用在商场衣服内侧的标签上,电子元器件以及公交站。在过去,它们不可能给任何东西提供动力来源,但是华盛顿大学的研究团队的最新成果使得它的射频信号能够转化成为电能。 所产生的电能其实是很小的,并不足以支撑运行智能手机,但是足够运行那些对电量要求较低的物联网设备。根据华盛顿大学 Sensor Lab 的研究人员 Aaron Parks 的介绍:摆脱对传统电池的依赖,可以让设备在不介入任何物理硬件操作的前提下,自己运行上几十年的时间! 这种技术可以让物联网设备正如智能手机一样去运行一些应用程序,使得物联网设备正式迈入到了计算设备的范畴当中。如今,计算化的 RFID 技术已经成为了现代计算领域这个大的系统中的一部分内容。 尽管这对于未来的物联网行业来说意义非同凡响,但是它还没有正式进入到功能测试环节。华盛顿大学预计在不远的未来会深入进行测试,保证新的传输协议(名字叫做WISP)能够在现实世界中真正发挥其功能。 对于物联网行业来说,电池一直依赖都是非常大的难题,没有人愿意爬高爬下,比如去金门大桥的桥顶上去摘下一个感应器,又或者在一大片农庄田地里眯着眼去寻找一颗没有电了的传感器。让传感器能够自行供给电力,无需人工维护,这是彻底解放物联网领域巨大潜力的关键环节。 只是不要期望一夜之间就会实现,摆在物联网设备面前的路,依然很长。 本文转自d1net(转载)

优秀的个人博客,低调大师

Hutool 5.3.9 发布,目标无 issue 遗留

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当; Hutool是项目中“util”包友好的替代,它节省了我们对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。 ------------------------------------------------------------------------------------------------------------------- 好久不发新闻了,Hutool依旧在快速迭代,力争issue和pr双清。 PS:Hutool的完善和进步离不开大家的献言献策和pr贡献,但是我们不可能面面俱到,用户提的问题也不可能全部解决,未能解决的问题主要以下几个方面: 1、用户提的issue简单一句,无法理解或者复现问题,我只能关闭。 2、用户提出增加XXX工具类,此类需求评估后如果无法完成,我也会直接关闭,希望理解。 3、用户提供了非常好的工具类或者工具方法,但是pr代码混乱,甚至依赖非常多的第三方库,经过审查确实不能合并,关闭之。 4、用户提供了超出作者能力范围的算法(我看不懂……),考虑到后期维护问题,只能忍痛拒绝。 Hutool作为一个基础工具库,不再是开源初期作者的一个玩具,每一次升级都要为大多数用户考虑,因此代码的修改会更加慎重,希望大家理解,也希望大家依旧给与Hutool更多的帮助,力争让Hutool像Apache全家桶一样被大家所认可。 ------------------------------------------------------------------------------------------------------------------- 5.3.9 (2020-07-12) 新特性 【core 】 DateUtil增加formatChineseDate(pr#932@Github) 【core 】 ArrayUtil.isEmpty修改逻辑(pr#948@Github) 【core 】 增强StrUtil中空判断后返回数据性能(pr#949@Github) 【core 】 deprecate掉millsecond,改为millisecond(issue#I1M9P8@Gitee) 【core 】 增加LocalDateTimeUtil(issue#I1KUVC@Gitee) 【core 】 Month增加getLastDay方法 【core 】 ChineseDate支持到2099年 Bug修复 【core 】 修复NumberUtil.partValue有余数问题(issue#I1KX66@Gitee) 【core 】 修复BeanUtil.isEmpty不能忽略static字段问题(issue#I1KZI6@Gitee) 【core 】 修复StrUtil.brief长度问题(pr#930@Github) 【socket 】 修复AioSession构造超时无效问题(pr#941@Github) 【setting】 修复GroupSet.contains错误(pr#943@Github) 【core 】 修复ZipUtil没有调用finish问题(issue#944@Github) 【extra 】 修复Ftp中ArrayList长度为负问题(pr#136@Github) 【core 】 修复Dict中putAll大小写问题(issue#I1MU5B@Gitee) 【core 】 修复POI中sax读取数字判断错误问题(issue#931@Github) 【core 】 修复DateUtil.endOfQuarter错误问题(issue#I1NGZ7@Gitee) 【core 】 修复URL中有空格转为+问题(issue#I1NGW4@Gitee) 【core 】 修复CollUtil.intersectionDistinct空集合结果错误问题 【core 】 修复ChineseDate在1996年计算错误问题(issue#I1N96I@Gitee)

优秀的个人博客,低调大师

真正无感知的堡垒机----sshfortress

SSHfortress 中文 English 下载文件尽量到github去下载,因为目前官网的带宽很小 社区版完全免费,用户无须注册和授权文件,版本区别。 这个说明是介绍如何安装sshfortress系统,它有一个Web管理界面greatfortress是用java实现的用来可示化的增加账号、资产等功能;后端sshfortress是在openssh的基础上开发的功能,好了往下面看如何安装和配置吧。 目录 产品简介 功能 注意 依赖 安装 演示视频 如何使用 产品简介 sshfortress堡垒机集中了运维身份鉴别、账号管控、系统操作审计等多种功能。基于协议反向代理实现,通过反向代理的方式实现对 SSH 、SCP 及 SFTP 协议的数据流进行全程记录。统一运维入口,统一用户与主机帐号间的权限关系,防止内部数据泄密。 功能 堡垒机具备操作审计、职权管控、安全认证、高效运维等功能。 操作审计 多面记录运维人员的操作行为,作为事件追溯的保障和事故分析的依据。 运维操作记录: 操作失误、恶意操作、越权操作详细记录。 Linux命令审计: 可提取命令符审计。 文件传输审计: 支持远程桌面文件传输、SFTP的原文件审计。 终端录制回放: 支持终端录制ssh操作过程,完全兼容linux自带工具scriptreplay进行回放。回放文件存放路径/var/log/sshfortress_playback,按年月日归类。 职权管控 通过账号管控和权限组管理,实现分职权进行人员和资产的管理。 账号管控: 运维账号唯一,解决共享账号、临时账号、滥用权限等问题。 权组管理: 按照人员、部门组织、资源组,建立人员职责与资源分配的授权管理。 高效运维 原生实现,不改变用户使用习惯,仿佛没有使用堡垒机一样。 C/S架构运维接入: 支持SSH、SCP、SFTP协议。 多运维工具: 支持PuTTY、SecureCRT、Xshell等工具。 注意 sshfortress将接管22端口,所以在这之前你需要另外编译安装一个openssh并监听其他端口(22端口以外)以便你远程连接 https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/ # wget https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/openssh-8.1p1.tar.gz # tar zxvf openssh-8.1p1.tar.gz # cd openssh-8.1p1/ # ./configure --prefix=/usr/local/openssh2233 # make -j4; make install # sed -i '1i\Port 2233' /usr/local/openssh2233/etc/sshd_config # sed -i '2i\PermitRootLogin yes' /usr/local/openssh2233/etc/sshd_config # /usr/local/openssh2233/sbin/sshd 可以创建一个开机启动项 rc-local在centos7以前是加载的,之后不再开机加载了,现在我们打开它 [root@centos8 tmp]# cat /usr/lib/systemd/system/rc-local.service [Unit] Description=/etc/rc.local ConditionPathExists=/etc/rc.local [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target # systemctl daemon-reload # systemctl enable rc-local # chmod +x /etc/rc.local # echo "/usr/local/openssh2233/sbin/sshd" >> /etc/rc.local 友情提示centos8开始启用了nftables而不是iptables,如果你不熟悉规则的添加,最好清空规则 # nft flush ruleset 依赖 glibc 2.17+ mysql 5.6+ or MariaDB jdk 1.8 tomcat 8 sshfortress 安装 进入资源页按需下载即可,https://sshfortress.com/downloads/ 或者 https://github.com/sshfortress/sshfortress/releases 进行下载 apache-tomcat-8.5.31.tar.gz 09-Jan-2020 11:21 9M audit_sec.sql 09-Jan-2020 16:07 10M greatfortress.tar.gz 10-Jan-2020 09:52 65M jdk-8u172-linux-x64.tar.gz 09-Jan-2020 11:22 182M sshfortress-1.6.1.sha256 09-Jan-2020 16:14 155 sshfortress-1.6.1.tar.gz 09-Jan-2020 15:58 10M jdk # tar zxvf jdk-8u172-linux-x64.tar.gz -C /usr/local/ # ln -s /usr/local/jdk1.8.0_172/ /usr/local/jdk # echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile # echo "export JRE_HOME=/usr/local/jdk/jre" >> /etc/profile # echo "export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib:\${CLASSPATH}" >> /etc/profile # echo "export PATH=\${JAVA_HOME}/bin:\${JRE_HOME}/bin:/usr/local/mysql/bin:\${PATH}" >> /etc/profile # source /etc/profile mysql 选项1: 源码编译 # yum -y install make gcc-c++ cmake bison-devel bison ncurses-devel libgnomeui-devel perl-Module-Install bzip2 libtirpc-devel # wget https://github.com/sshfortress/sshfortress/releases/download/1.6.1/mysql-5.7.16.tar.gz # wget https://github.com/sshfortress/sshfortress/releases/download/1.6.1/boost_1_59_0.tar.bz2 # tar jxvf boost_1_59_0.tar.bz2 -C /tmp # tar zxvf mysql-5.7.16.tar.gz # groupadd mysql;useradd -r -g mysql -s /bin/false -M mysql # cd mysql-5.7.16/ # cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DINSTALL_DATADIR=/usr/local/mysql/data \ -DSYSCONFDIR=/usr/local/mysql/etc \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_general_ci \ -DEXTRA_CHARSETS=all \ -USER=mysql \ -DWITH_MYISAM_STORAGE_ENGINE=1 \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_ARCHIVE_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITH_MEMORY_STORAGE_ENGINE=1 \ -DWITH_BOOST=/tmp/boost_1_59_0 # make -j4; make install # chown -R mysql.mysql /usr/local/mysql # cp -f support-files/mysql.server /etc/init.d/mysqld # mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data # /etc/init.d/mysqld start # 初始密码,初始化的时候可以看到 <temporary password 'nibmcstse9!i'> # mysql -uroot -p'NiBMcstse9!i' --connect-expired-password -e "alter user 'root'@'localhost' identified by 'SSHfortress123@';CREATE USER 'sshfortress'@'%' IDENTIFIED BY 'SSHfortress123@';GRANT ALL PRIVILEGES ON *.* TO 'sshfortress'@'%' IDENTIFIED BY 'SSHfortress123@' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;flush privileges;" # mysql -uroot -p'SSHfortress123@' -e "create database audit_sec; use mysql;create user 'audit'@'127.0.0.1' identified by 'audit'; grant all privileges on audit_sec.* to 'audit'@'127.0.0.1';" # mysql -uroot -p'SSHfortress123@' -e "set global log_bin_trust_function_creators=1; set global explicit_defaults_for_timestamp=1;set global sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';" # mysql -uroot -p'SSHfortress123@' audit_sec <audit_sec.sql 为了防止每次重启失效,所以把它写入到配置文件中如下: #[root@centos8 local]# cat etc my.cnf [mysqld] log_bin_trust_function_creators="on" explicit_defaults_for_timestamp="on" sql_mode="NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES" # systemctl enable mysqld # /etc/init.d/mysqld restart 选项2: YUM安装 这里centos8.0 mysql 8.0为例 # yum install mysql-server # echo "skip_ssl" >> /etc/my.cnf.d/mysql-server.cnf # echo "log_bin_trust_function_creators=on" >> /etc/my.cnf.d/mysql-server.cnf # echo "explicit_defaults_for_timestamp=on" >> /etc/my.cnf.d/mysql-server.cnf # echo "sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES" >> /etc/my.cnf.d/mysql-server.cnf # systemctl enable mysqld # systemctl restart mysqld # mysql -e "create user audit@'127.0.0.1' identified by 'audit'; grant all privileges on *.* to audit@'127.0.0.1' with grant option;" # mysql -e "create database audit_sec;" # mysql audit_sec < audit_sec.sql 选项3: APT安装 这里以Debian 9.9.0 MariaDB 10.1.41为例 # apt-get install mysql-server # systemctl enable mariadb # mysql -e "create user audit@'127.0.0.1' identified by 'audit'; grant all privileges on *.* to audit@'127.0.0.1' with grant option;" # mysql -e "create database audit_sec;" # mysql audit_sec < audit_sec.sql tomcat # tar zxvf apache-tomcat-8.5.31.tar.gz -C /usr/local/ # ln -s /usr/local/apache-tomcat-8.5.31/ /usr/local/tomcat # rm -rf /usr/local/tomcat/webapps/* # tar zxvf greatfortress.tar.gz -C /usr/local/tomcat/webapps # sed -i 's/192.168.7.3/x.x.x.x/g' /usr/local/tomcat/webapps/greatfortress/common/layui/layui.js # /usr/local/tomcat/bin/catalina.sh start x.x.x.x 是你的监听地址 http://x.x.x.x:8080/greatfortress 帐号:fortress 密码 hilookhere 启动tomcat后,首次登录有点慢 sshfortress # tar zxvf sshfortress-x.x.x.tar.gz # cd sshfortress-x.x.x # ./install.sh 演示视频 https://sshfortress.com/en/video.html 如何使用 登录名加两个减号加资产ID Example: ssh name--ID@x.x.x.x scp ll.jpg name--ID@x.x.x.x:/tmp sftp name--ID@x.x.x.

优秀的个人博客,低调大师

Android -- 处理ViewPager的notifyDataSetChanged无刷新

Viewpager在调用notifyDataSetChanged()时,界面无刷新 Viewpager在调用notifyDataSetChanged()时,界面无刷新,它确实影响我们功能的实现了。可能选择为Viewpager重新设置一遍适配器adapter,达到刷新的目的。但是这种方法在大多数情况下,是有问题的。 查看方法 super.notifyDataSetChanged()调用的是PagerAdapter.notifyDataSetChanged() /** * This method should be called by the application if the data backing this adapter has changed * and associated views should update. */ public void notifyDataSetChanged() { mObservable.notifyChanged(); } 注释里说到,当附加在适配器上的数据发生变化时,应该调用该方法刷新数据。该方法调用了一个mObservable .notifyChanged(); 我们继续跟进这个方法,进入DataSetObservable类中,发现这样一段代码: /** * Invokes {@link DataSetObserver#onChanged} on each observer. * Called when the contents of the data set have changed. The recipient * will obtain the new contents the next time it queries the data set. */ public void notifyChanged() { synchronized(mObservers ) { // since onChanged() is implemented by the app, it could do anything, including // removing itself from {@link mObservers} - and that could cause problems if // an iterator is used on the ArrayList {@link mObservers}. // to avoid such problems, just march thru the list in the reverse order. for (int i = mObservers .size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } } 这都不是重点,重点我们来看这个mObservers的类型是一个抽象类DataSetObserver,里面只有两个未实现的方法,都有谁使用了这个抽象类呢,其中我们发现了Viewpager的身影。进入viewpager,我们终于找到了viewpager中控制数据变更的重点方法dataSetChanged ,这个方法如下: void dataSetChanged () { // This method only gets called if our observer is attached, so mAdapter is non-null. boolean needPopulate = mItems .size() < mOffscreenPageLimit * 2 + 1 && mItems.size() < mAdapter.getCount(); int newCurrItem = mCurItem ; boolean isUpdating = false; for (int i = 0; i < mItems.size(); i++) { final ItemInfo ii = mItems .get(i); final int newPos = mAdapter.getItemPosition(ii.object ); if (newPos == PagerAdapter.POSITION_UNCHANGED ) { continue; } if (newPos == PagerAdapter.POSITION_NONE) { mItems.remove(i); i--; if (!isUpdating) { mAdapter.startUpdate( this); isUpdating = true; } mAdapter.destroyItem( this, ii.position , ii.object); needPopulate = true; if (mCurItem == ii.position ) { // Keep the current item in the valid range newCurrItem = Math. max(0, Math.min(mCurItem, mAdapter.getCount() - 1)); needPopulate = true; } continue; } if (ii.position != newPos) { if (ii.position == mCurItem ) { // Our current item changed position. Follow it. newCurrItem = newPos; } ii. position = newPos; needPopulate = true; } } if (isUpdating) { mAdapter.finishUpdate( this); } Collections. sort(mItems, COMPARATOR); if (needPopulate) { // Reset our known page widths; populate will recompute them. final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (!lp.isDecor ) { lp. widthFactor = 0.f; } } setCurrentItemInternal(newCurrItem, false, true); requestLayout(); } } 重点看这样一行代码: final int newPos = mAdapter.getItemPosition(ii.object ); if (newPos == PagerAdapter.POSITION_UNCHANGED ) { continue ; } Called when the host view is attempting to determine if an item’s position has changed. ReturnsPOSITION_UNCHANGEDif the position of the given item has not changed orPOSITION_NONEif the item is no longer present in the adapter. The default implementation assumes that items will never change position and always returnsPOSITION_UNCHANGED. 意思是如果item的位置如果没有发生变化,则返回POSITION_UNCHANGED。如果返回了POSITION_NONE,表示该位置的item已经不存在了。默认的实现是假设item的位置永远不会发生变化,而返回POSITION_UNCHANGED 解决方案 所以我们可以尝试着修改适配器的写法,覆盖getItemPosition()方法,当调用notifyDataSetChanged时,让getItemPosition方法人为的返回POSITION_NONE,从而达到强迫viewpager重绘所有item的目的。 class SearchAdapter extends PagerAdapter { private int mChildCount = 0; @Override public void notifyDataSetChanged() { mChildCount = getCount(); super.notifyDataSetChanged(); } @Override public int getItemPosition(Object object) { if ( mChildCount > 0) { mChildCount --; return POSITION_NONE; } return super.getItemPosition(object); } } 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4232614.html,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册