public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
private final ProgressDialog progressDialog;
public MyTask(Context ctx) {
progressDialog = gimmeOne(ctx);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// actually could set running = false; right here, but I'll
// stick to contract.
cancel(true);
}
});
}
@Override
protected void onPreExecute() {
progressDialog.show();
}
@Override
protected void onCancelled() {
running = false;
}
@Override
protected Void doInBackground(Void... params) {
while (running) {
// does the hard work
}
return null;
}
// ...
}
这两天要用一个对象的传递始终找不到好的方法,后来在传递bitMap时这个对象时有了点启发
可以讲一个类扩展为implement Serializable interface
//传递:
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
在Qt应用中强制使用横屏或竖屏
摘要:本文介绍怎么在Qt for Symbian程序中即使手机水平状态发生变化的时候强制使用横屏或竖屏。
对于带有水平传感器的Symbian手机,在用户将手机从横屏模式(Landscape)切换到竖屏模式(Portrait)时,系统会自动调整手机的屏幕显示方向,满足用户正常的使用需要。屏幕横宽比的变化,需要应用调整窗口的布局,以保证更好的用户体验。
但是在某些特殊场合中(比如游戏),开发者可能希望即使手机的水平状态已经变化,需要屏幕继续保持原来的屏幕方向,提示用户只能在横屏或者竖屏方向上使用当前的应用,这就需要通过设置,让手机屏幕强制处在横屏或者竖屏状态。
Qt的当前版本(Qt-4.6.2)并没有提供直接控制Symbian 手机屏幕模式的API,需要通过使用Symbian的API来完成。设置API函数为:CAknAppUi::SetOrientationL(); 在Qt中的使用显示代码如下:
#ifdef Q_OS_SYMBIAN
void MyWidget::setPortraitMode()
{
CAknAppUi *aknAppUi = dynamic_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
if (aknAppUi)
aknAppUi->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait);
}
void MyWidget::setLandscapeMode()
{
CAknAppUi *aknAppUi = dynamic_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
if (aknAppUi)
aknAppUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape);
}
#endif
要使用上面代码中的Symbian函数,需要在代码里把symbian的几个相关头文件加入到源码中
#ifdef Q_OS_SYMBIAN #include <eikenv.h> #include <coemain.h> #include <aknappui.h> #endif
并且需要在Qt的.pro工程文件中加入以下内容,保证应用能够编译和链接
symbian {
LIBS += -lconnmon -lcone -lavkon
}
注意:该功能在模拟器上不能模拟,但是在Symbian手机上工作正常。
*.gif decode 前面已经说过 今天不打算再说了
鉴于自定义组件View 很多人反映看不懂 所以今天想以此为例 再详细演示一遍
主要目标: 定义 TypegifView 用于显示目标*.gif 且 extends View
[代码 步骤]
1. 定义xml所需 属性描述字串 在res\values 新增文件:attra.xml 定义如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TypegifView">
<!-- set *.gif source, as resource id -->
<attr name="src" format="integer" />
<!-- set frequency to update bitmap, as int-->
<attr name="delta" format="integer" />
</declare-styleable>
</resources>
2. 定义TypegifView 构造函数 供*.java调用:
public TypegifView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
如何使用:
TypegifView tgView = new TypegifView(this);
3. 定义TypegifView 构造函数 供*.xml调用 且根据传入属性描述字串 设置相应函数
public TypegifView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.TypegifView);
int n = ta.getIndexCount();
for(int i =0;i < n;i++){
int attr = ta.getIndex(i);
switch(attr){
case R.styleable.TypegifView_src:
int id = ta.getResourceId(
R.styleable.TypegifView_src, 0);
setSrc(id);
case R.styleable.TypegifView_delta:
int idelta = ta.getInteger(R.styleable.TypegifView_delta, 1);
setDelta(idelta);
default:
break;
}
}
ta.recycle();
}
public void init(){
// do some initial
}
public void setSrc(int id){
gHelper = new TypegifOpenHelper();
gHelper.read(this.getResources().openRawResource(id));
bmp=gHelper.getFrame(0);
Thread updateTimer =new Thread(this);
updateTimer.start();
}
public void setDelta(int is){
delta = is;
}
如何使用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gif="http://schemas.android.com/apk/res/org.android.view"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- to introduce gif namespace -->
<org.android.view.TypegifView xmlns:gif="http://schemas.android.com/apk/res/org.android.view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
gif:src="/blog_article/@raw/kitty/index.html"
gif:delta="10"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="-----------[我是分割线!]-------------"
/>
</LinearLayout>
4. 属性:src delta 设置:
public void setSrc(int id){
gHelper = new TypegifOpenHelper();
gHelper.read(this.getResources().openRawResource(id));
bmp=gHelper.getFrame(0);
Thread updateTimer =new Thread(this);
updateTimer.start();
}
public void setDelta(int is){
delta = is;
}
5. 取得该gif所占用的宽度 高度 如果没有该函数 该组件后面不可以再有别的控件 个人猜测其返回值会是整个屏幕
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec),
measureHeight(heightMeasureSpec));
}
private int measureWidth(int measureSpec) {
return gHelper.getWidth();
}
private int measureHeight(int measureSpec) {
return gHelper.getHeigh();
}
6. 该View 执行画的回调函数:
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawBitmap(bmp, 0,0,new Paint());
bmp=gHelper.nextBitmap();
}
7. 定义延时Thread 定时更新下一张bitmap
public void run() {
// TODO Auto-generated method stub
while(true){
try{
this.postInvalidate();
Thread.sleep(gHelper.nextDelay()/delta) ;
}catch(Exception ex){
}
}
}
9. emulator 运行截图:
10. 因为描述的比较不细致 所以补上全部代码 供大家分享
结束?不能结束 因为*.gif 是不断循环的
不过我在阅读楼主提供的代码时发现有一个问题,就是readShort()函数的实现
// read 8 bit data
protected int readShort() {
// read 16-bit value, LSB first
return read() | (read() << 8 );
}
这个考虑的是小端字节序存储吗?为何确定就是小端字节序呢,而没有考虑别的方式呢,这个与PC上Java编程时通过二进制流读取来获取short值的方法是一致的吗?
还是代码的比较方便。学习了。
具体例子可以看 ApiDemo 里的BitmapDecode例子