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