2012 苹果发布了ipad mini和iphone 5 ,微软发布win 8,wp8,谷歌推出果冻豆,并推出Nexus 7,十八大的召开,还有因玛
雅人预言是世界末日论等等在2012发生的大事.... 所以2012注定不是一个平静之年。我在去年闲暇时间看了不少各种仿某某的技术文
章,如仿微信登陆界面 欢迎界面qq界面以及仿网易新闻上面的什么什么..... 总之有各种仿。
仿照未必是一件坏事,先要学会仿照,接着理解他,吃透他,等你懂了一定原理后,发现以前的东西不怎么够好,需要改进,那
么通过你的改进,使你的软件用户体验更好,我想这应该就是微创新吧。
在这里引用下名人的话以增加文章的深度啊
“ 用户体验的创新是决定互联网应用能否受欢迎的关键因素,这种创新叫'微创新','微创新'引领互联网新的趋势和浪潮 ”。——周鸿祎
好了引用完名人的话总算啰嗦一把,下面继续啰嗦哈,直接切入正题
为了跟进潮流,我也来 仿某某,,以后再学习微创新。今天我仿得是网站最喜欢用的文章分页时的页码,看看效果图与代码你就知
道了。
package com.manymore13.page; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.security.acl.LastOwnerException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class PageNumDemo extends JFrame { private int sumPage = 35;//总的页码数,这里作为Demo,就写个固定值 private int currentPage=1; // 默认是第一页 private JPanel pageBtns = new JPanel(); // 存放一系列页码按钮 默认流布局 PageNumDemo() { Image image = null; try { image = ImageIO.read((this.getClass().getResource("./image/logo.png"))); } catch (IOException e){ e.printStackTrace(); } this.setIconImage((Image)image);// 设置窗口左上角的图标,我这里是个快播的图标 this.setTitle("仿网页分页页码"); //设置窗口标题 this.setLayout(new FlowLayout(15,20,20)); //设置JFrame的布局 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 档点击叉叉时,窗口可关闭 this.setVisible(true); // 窗口可见 this.setLocationRelativeTo(null); //窗口居中 setPageBottom(1); //默认显示第一页 ,设置页码布局 this.setSize(850, 118); // 窗口宽高 this.setResizable(true);// 设置窗口可拉伸 } /** * * @param selectNum 你按下的页码数字,例如你按下按钮5,就需要传个整型5 */ private void setPageBottom(int selectNum) { pageBtns.removeAll(); if(selectNum<=0 || selectNum>sumPage){ return; } // 这个是显示数字按钮的总个数,不包括首页 尾页等其他按钮 int countNumBtn = 9; // 首页 1 2 3 4 5 6 7 8 9 尾页 int half = countNumBtn/2; int startNum = 0; int endNum = 0; JButton btnFistPage = new JButton("首页"); btnFistPage.setActionCommand("首页"); btnFistPage.setToolTipText("首页"); btnFistPage.setToolTipText("首页"); btnFistPage.addActionListener(new BottomPageButtonAction()); JButton btnLastPage = new JButton("末页"); btnLastPage.setActionCommand("末页"); btnLastPage.addActionListener(new BottomPageButtonAction()); btnLastPage.setToolTipText("共"+sumPage+"页"); Container con = this.getContentPane(); con.invalidate(); pageBtns.add(btnFistPage); if(selectNum !=1){ JButton btnPrePage = new JButton("上一页"); btnPrePage.setActionCommand("上一页"); btnPrePage.setToolTipText("上一页是第"+(currentPage-1>=1?--currentPage:1)+"页"); btnPrePage.addActionListener(new BottomPageButtonAction()); pageBtns.add(btnPrePage); } // 下面开始计算从左至右数字键(JButton)上的text int minBtnNum = selectNum-half; int maxBtnNum = selectNum+half; if(minBtnNum>0 && maxBtnNum<=sumPage){ startNum = minBtnNum; endNum = maxBtnNum; }else if(minBtnNum<=0){ startNum =1; endNum = countNumBtn>sumPage?sumPage:countNumBtn; }else if(maxBtnNum>sumPage){ startNum = sumPage >countNumBtn?sumPage-(countNumBtn-1):1; endNum = sumPage; } for(int i=startNum;i<=endNum;i++){ JButton btn = new JButton(); btn.addActionListener(new BottomPageButtonAction(i)); btn.setActionCommand("数字"); btn.setToolTipText("第"+i+"页"); btn.setText(i+""); if(i==selectNum){ btn.setBackground(Color.red); }else{ btn.setBackground(Color.white); } pageBtns.add(btn); } if(selectNum != sumPage){ JButton btnNextPage = new JButton("下一页"); btnNextPage.setActionCommand("下一页"); btnNextPage.setToolTipText("下一页是第"+(currentPage+1<=sumPage?++currentPage:sumPage)+"页"); btnNextPage.addActionListener(new BottomPageButtonAction()); pageBtns.add(btnNextPage); } pageBtns.add(btnLastPage); con.validate(); this.add(pageBtns); } // 页码事件处理 class BottomPageButtonAction implements ActionListener { int btnNumText =0; BottomPageButtonAction(){ } BottomPageButtonAction(int num){ btnNumText = num; } @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); System.out.println(command); if(command.equals("首页")){ // setPageBottom(1); // 首页就是第一页,所以直接传个1 currentPage =1; }else if(command.equals("上一页")){ setPageBottom(currentPage-1>=1?--currentPage:1); }else if(command.equals("下一页")){ setPageBottom(currentPage+1<=sumPage?++currentPage:sumPage); }else if(command.equals("末页")){ setPageBottom(sumPage); // 末页是最后的页数 currentPage = sumPage; }else if(command.equals("数字")){ setPageBottom(btnNumText); currentPage = btnNumText; } System.out.println("当前是第 "+currentPage+"页"); } } /** * @param args */ public static void main(String[] args) { new PageNumDemo(); } }
小功能简单实现了下,代码里注释很清楚了,JFrame里添加一个Jpanel,Jpanel里添加相应的JButton,由于Jpanel是流布局,所以Button在被添加时一定要按顺序添加。
任何开发语言都有一定的难度,所以大家在学习的过程中不要感到枯燥,要有耐心。废话不多说,下面为大家介绍Android Widget添加自定义控件。首先看一个引用:
ARemoteViews object (and, consequently, an App Widget) can support thefollowing layout classes:
*FrameLayout
*LinearLayout
*RelativeLayout
Andthe following widget classes:
*AnalogClock
*Button
*Chronometer
*ImageButton
*ImageView
*ProgressBar
*TextView
Descendantsof these classes are not supported.
可见我们widget里面可以使用的控件只 有:AnalogClock,Button,Chronometer,ImageButton,mageView,ProgressBar,TextView 这7种,Listview,Editview,Scrollview等这些很常用的控件都无法在我们的Widget中使用。而其实这所有的控件的源码都是 放在framework/base/core/java/android/widget这个目录下的,这7种控件之所以可用是因为加了 @RemoteView这个标签,我们可以看一下源码:
AnalogClock.java:39:@RemoteView
AnalogClock.java-40-publicclass AnalogClock extends View {
ImageButton.java:66:@RemoteView
ImageButton.java-67-publicclass ImageButton extends ImageView {
…..
所以我们想要在widget中使用诸如Listview这样的控件的话,需要自己写一个和Listview一模一样的类,加上@RemoteView标签,并拷贝到framework/base/core/java/android/widget这个目录下。
然后我们就可以在Widget中使用我们写的这个控件了,由于他和其他可用控件一样都有@RemoteView标签,那么他也就能被RemoteView对象所识别了。
既然原理我们已经知道了,那么可以按下面的步骤实现(以我自定义一个AnalogClock为例):
1.首先我完完整整的拷贝了源码中的AnalogClock.java命名为MyClock.java到framework/base/core/java/android/widget这个目录下,然后按自己的需求修改了代码。
2.这个MyClock.java用到的资源文件必须存放在frameworks/base/core/res/res目录下。而且必须是这样的方式引用:com.android.internal.R.drawable.*
不过如果这样做的话更换资源不太方便,我们知道每个系统控件都有个style文件,所以我的做法是:
先看系统的AnalogClock.java的style源文件:
…..
frameworks/base/core/res/res/values/attrs.xml:
所以我们想要在widget中使用诸如Listview这样的控件的话,需要自己写一个和Listview一模一样的类,加上@RemoteView标签,并拷贝到framework/base/core/java/android/widget这个目录下。
然后我们就可以在Widget中使用我们写的这个控件了,由于他和其他可用控件一样都有@RemoteView标签,那么他也就能被RemoteView对象所识别了。
既然原理我们已经知道了,那么可以按下面的步骤实现(以我自定义一个AnalogClock为例):
1.首先我完完整整的拷贝了源码中的AnalogClock.java命名为MyClock.java到framework/base/core/java/android/widget这个目录下,然后按自己的需求修改了代码。
2.这个MyClock.java用到的资源文件必须存放在frameworks/base/core/res/res目录下。而且必须是这样的方式引用:com.android.internal.R.drawable.*
不过如果这样做的话更换资源不太方便,我们知道每个系统控件都有个style文件,所以我的做法是:
先看系统的AnalogClock.java的style源文件:
frameworks/base/core/res/res/values/attrs.xml:
private Drawable mMinuteHand;
public MyClock(Context context, AttributeSet attrs, intdefStyle) {
super(context,attrs, defStyle);
Resources r = context.getResources();
TypedArray a = context.obtainStyledAttributes(attrs,com.android.internal.R.styleable.AnalogClock,defStyle,0);
mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);//这里就是调用attrs.xml里的参数
if(mMinuteHand== null){
mMinuteHand= r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);//而这里是调用系统frameworks/base/core/res/res目录下的资源
}
}
我自己在widget的布局配置文件里面定义:
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_widget_clockView"
android:hand_minute="@drawable/minute_white"//这里就是引用本地drawable下的资源
android:layout_width="80dp"
android:layout_height="80dp"
/>
这一块比较绕。。我也是反复编译源码测试才成功。
3.这个时候基本上工作已经完成一大半了,我们需要编译整个SDK。但是注意,我在编译过程中出现了各种编译错误,而且提示都是unknown,十分让人费解,最终我总结出一套成功率极高编译方法。
先在根目录make-j4编译整个纯净的源码(注意不要添加任何我们自己定义的类和资源),大约1-2小时成功编译结束后,再把我们自定义的类和资源等拷贝到framework下,再一次在根目录make-j4编译。
如果要测试我们添加的代码,需要在全部编译成功后,执行emulator命令启动一个新编出的模拟器,然后在上面安装我们的APK。
本文链接
关于 WindowsPhone RadControls
RadBusyIndicator控件允许您显示动画指示您的应用程序忙等待异步操作完成。控件附带的预定义的动画,可以轻松地设置一堆。您可以定义自己的动画和RadBusyIndicator控件中使用它们。下面的屏幕快照显示的默认状态的控件:
您可以使用以下属性微调 RadBusyIndicator 的行为:
- Content - 定义动画旁显示的内容。此内容可能给正在由控件表示的进程有关的有用信息
- ContentTemplate - 定义用来表示的内容属性中定义的内容的模板
- ContentPosition - 接受从 ContentPosition 枚举的定义位置的内容与指标动画的值的属性
- IsRunning - 一个布尔值,定义或不 RadBusyIndicator 控件是否显示动画的属性。
- IndicatorAnimationStyle - 接受它定义实际指标动画样式实例。可以用于定义一个自定义指示器的动画。对此属性的详细信息看看自定义动画主题。
若要使用 RadBusyIndicator 为 Windows Phone,以下引用是必需的:
- Telerik.Windows.Core.dll
- Telerik.Windows.Controls.Primitives.dll
IsRunning 属性
RadBusyIndicator 允许播放和停止它的动画通过将IsRunning属性设置为 true 或 false。IsRunning属性发生更改时,也将更改 RadBusyIndicator 的可见性。当IsRunning设置为 true RadBusyIndicator 变为可见,否则它处于折叠状态。
Content 和 ContentTemplate
Content 和 ContentTemplate 属性可以用于定义描述表明由 RadBusyIndicator 的进展的附加内容。
ContentPosition 属性
ContentPosition 属性定义的内容与指标动画的位置。此属性接受从 ContentPosition 枚举的值,它们,如下所示
- 左-内容位于左侧的指示器动画
- 顶部-内容位于上方的指示灯动画
- 权利-内容位于右侧的指示器动画
- 底部-指示器动画下方放置内容
Sample 1:
x:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:telerikPrimitives="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Primitives"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot 是包含所有页面内容的根网格-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel 包含应用程序的名称和页标题-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="RadControls for WindowsPhone" />
<TextBlock x:Name="PageTitle" Text="BusyIndicator" Margin="9,-7,0,0" />
</StackPanel>
<!--ContentPanel - 在此处放置其他内容-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Grid.Row