当前位置:  编程技术>移动开发
本页文章导读:
    ▪NSDate展示和时区的关系        NSDate显示和时区的关系在网上看到一篇介绍NSDate的博文。在它的“NSDate初始化“章节,说在使用  NSLog(@"当前时间 date = %@",[NSDate date]);时,显示出来的时间不是自己时区的时间,比我们小8个.........
    ▪ Fragment的容易使用        Fragment的简单使用最近一直有点忙,刚刚看到一个朋友的留言提到Fragment中加载ListView的问题,这里写了一个非常简单的测试,至于对Fragment的增、删、改实现动态布局构建灵活的UI,以后有时.........
    ▪ Qt的Graphics-View框架跟OpenGL结合详解       Qt的Graphics-View框架和OpenGL结合详解Qt的Graphics-View框架和OpenGL结合详解 演示程序下载地址:这里 程序源代码下载地址:这里 这是一篇纯技术文,介绍了这一个月来我抽时间研究的成果。 Qt中.........

[1]NSDate展示和时区的关系
    来源: 互联网  发布时间: 2014-02-18
NSDate显示和时区的关系

在网上看到一篇介绍NSDate的博文。在它的“NSDate初始化“章节,说在使用  NSLog(@"当前时间 date = %@",[NSDate date]);时,显示出来的时间不是自己时区的时间,比我们小8个小时。因此判断该问题是时区问题。

好,我承认作者判断的很对,但是他给出的解决方法,却令人很意外。这个点对于理解[NSDate date]有很大的误导和迷惑性。

他的部分代码如下:

// 获取当前日期

        NSDate *date = [NSDatedate];

       

        // 打印结果: 当前时间date = 2013-08-16 09:00:04 +0000

        NSLog(@"当前时间 date = %@",date);

       

        // 获取从某个日期开始往前或者往后多久的日期,此处60代表60秒,如果需要获取之前的,将60改为-60即可

        date = [[NSDate alloc]initWithTimeInterval:60 sinceDate:[NSDate date]];

       

        //打印结果:当前时间 往后60s的时间date = 2013-08-16 09:01:04 +0000

        NSLog(@"当前时间 往后60s的时间date = %@",date);

      

       PS:测试时时间是下午5点,但是得到的当前时间却是上午9点,相差了8小时,是时区的问题

      

       NSTimeZone *zone =[NSTimeZone systemTimeZone];

        

        NSInteger interval = [zonesecondsFromGMTForDate: date];

       

        NSDate *localDate =[date  dateByAddingTimeInterval: interval];

       

        // 打印结果 正确当前时间 localDate = 2013-08-16 17:01:04 +0000

        NSLog(@"正确当前时间 localDate = %@",localDate);

 

因为我们在正8区,而使用NSLog显示[NSDatedate]时,显示的时间是GTM时区的时间。

作者将[NSDate date]的结果加上8×60×60,得到的时间就是我们正8区看到的时间。

好吧,不得不说这个方法得到的结果是符合要求的,显示时间数字是一致的了。

下面说这个方法的不当之处。它给人一种误导,[NSDate date]得到的时间是应该加8小时,才能正确显示符合我们时区的时间。

何必呢?不就是要[NSDate date]符合本时区的时间数字显示出来吗?何必认为修改时间数值呢?

NSDate对象的显示结果不符合,却去修改对象本身,真真是舍本逐末。

 

刚好在stackoverflow.com上找到一帖,可以用来解释这个问题。呵呵。

http://stackoverflow.com/questions/4547379/nsdate-is-not-returning-my-local-time-zone-default-time-zone-of-device

 

My local and default time zone is GMT +5 but when I get date and time byNSDate it return me GMT date and time.

 

For example the code and output from my code while testing on device isas, [device time zone Islamabad GMT +5]

 NSTimeZone *lo = [NSTimeZonelocalTimeZone];

 NSLog(@" - current  local timezone  is %@",lo); // GMT +5

 

2010-12-28 20:56:11.785 Done[484:307]  - current local timezone  is  Local Time Zone (Asia/Karachi (GMT+05:00)offset 18000)

 

 NSTimeZone *df = [NSTimeZonedefaultTimeZone];

 NSLog(@" - current  default timezone  is %@",df); // GMT +5

2010-12-28 20:56:11.790 Done[484:307]  - current default timezone  is  Asia/Karachi (GMT+05:00) offset 18000

 

 NSDate *cDate = [NSDatedate];

 NSLog(@"current date byNSDate %@",cDate); //but NSDate show GMT

2010-12-28 20:56:11.794 Done[484:307] current date by NSDate2010-12-28 15:56:11 GMT

 

 

 NSDateFormatter*dateFormatter = [[NSDateFormatter alloc] init];

 dateFormatter.dateFormat =@"yyyy-MM-dd'T'HH:mm";

 //// NSTimeZone *gmt =[NSTimeZone ]

 NSTimeZone *gmt = [NSTimeZonetimeZoneWithAbbreviation:@"GMT+05:00"];

 [dateFormattersetTimeZone:gmt];

 NSString *timeStamp =[dateFormatter stringFromDate:[NSDate date]];

 NSLog(@" date stringobject  %@" ,timeStamp);   // string From Date is GMT +5

2010-12-28 20:56:11.802 Done[484:307]  date string object  2010-12-28T20:56

 

 NSDate *datef =[dateFormatter dateFromString:@"2010-12-28T20:56"];

 NSLog(@" date object%@" ,datef);  // the date form abovestring gives again GMT

2010-12-28 20:56:11.809 Done[484:307]  **date object 2010-12-28 15:56:00 GMT**

 

Why is NSDate not giving local current time? Please help...

 

这是一个巴基斯坦人的提问,他不明白为什么会这样?您明白了吗?你知道了怎么来正确地显示时间数字了吗?

 


    
[2] Fragment的容易使用
    来源: 互联网  发布时间: 2014-02-18
Fragment的简单使用

最近一直有点忙,刚刚看到一个朋友的留言提到Fragment中加载ListView的问题,这里写了一个非常简单的测试,至于对Fragment的增、删、改实现动态布局构建灵活的UI,以后有时间在讨论:

MainActivity:

package com.home.testfragment;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends FragmentActivity {
	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		setContentView(R.layout.main);
		ListView listView = (ListView) findViewById(R.id.fragment__first_list);
		List<String> list = new ArrayList<String>();
		list.add("张三");
		list.add("李四");
		list.add("王五");
		list.add("赵六");
		ArrayAdapter<String> adapter = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1, list);
		listView.setAdapter(adapter);
	}
}

FirstFragment:

package com.home.testfragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FirstFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_first, container, false);
	}
}

main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <fragment
        android:name="com.home.testfragment.FirstFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:tag="@+id/main_fragment_first" />

</LinearLayout>

fragment_first:

<?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"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="测试fragment的简单使用"
        android:textSize="20sp" />

    <ListView
        android:id="@+id/fragment__first_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

附上界面效果:






    
[3] Qt的Graphics-View框架跟OpenGL结合详解
    来源: 互联网  发布时间: 2014-02-18
Qt的Graphics-View框架和OpenGL结合详解

Qt的Graphics-View框架和OpenGL结合详解

演示程序下载地址:这里

程序源代码下载地址:这里


这是一篇纯技术文,介绍了这一个月来我抽时间研究的成果。

Qt中有一个非常炫的例子:Boxes,它展示了Qt能够让其Graphics–View框架和Qt的OpenGL模块结合起来,渲染出非常出色的效果。其实我私自认为凭这个程序,已经有很多游戏开发者关注Qt了,因为游戏开发一个非常常见的模块就是UI,一般情况下游戏引擎提供的UI模块比较弱,基本上都是游戏引擎+第三方GUI库进行结合的。但是Qt以其Graphics–View框架能够非常轻松地将UI控件嵌入场景中,而且能够和OpenGL底层共存,更重要的是,凭借着Qt的qss,Qt可以定制许多GUI元素,这是非常具有吸引力的。所以说,如果大家对游戏开发感兴趣,那么不妨看一下Qt。

好了,下面介绍一下前几天我制作并发布的一个demo。这个demo是对Boxes这个例子进行模仿,结合学习《OpenGL超级宝典》,制作而成的,由于最近比较忙,所以总共花了将近一个月才完成,不得不说效率有点儿低。

首先从MainWindow.cpp这个文件说起吧,一开始是要初始化MainWindow类的,这个类是继承QMainWindow的,这里重点说说它的构造函数:

MainWindow::MainWindow( QWidget* pParent ):
    QMainWindow( pParent )
{
    QGLWidget* pWidget = new QGLWidget( QGLFormat( QGL::SampleBuffers ), this );
    pWidget->makeCurrent( );
    // scene的内容
    GraphicsScene* pScene = new GraphicsScene( this );
    OpenGLView* pView = new OpenGLView( this );
    pView->setViewport( pWidget );
    pView->setViewportUpdateMode( QGraphicsView::FullViewportUpdate );
    pView->setScene( pScene );
    // 选择不同的着色器的时候进行着色器连接
    connect( pScene, SIGNAL( SwitchShader( const QString& ) ),
             pView, SLOT( SwitchShader( const QString& ) ) );
    connect( pScene, SIGNAL( SetLightPos( const QVector3D& ) ),
             pView, SLOT( SetLightPos( const QVector3D& ) ) );
    setCentralWidget( pView );
    setWindowTitle( tr( "Light for shader" ) );
    resize( 640, 360 );
}

首先在我们创建了一个QWidget,然后调用makeCurrent()成员函数,其实意思是让它的rendercontext设为当前的rendercontext。随后建立的是OpenGLView,这个OpenGLView是来自于QGraphicsView的,它的初始化和其祖先的并无二致,随后一句非常重要:setViewport(),它的作用是将QGLWidget设置为OpenGLView的viewport,这样的话背景的rendercontext不再是rastercontext而是OpenGLcontext了,否则场景的背景还是需要用CPU渲染的,效率低下。接着是两段建立连接的代码。最后设置的是窗口大小和标题什么的,一开始还是非常简单的。


接下来我们看看OpenGLView是怎么定义的:

class OpenGLView: public QGraphicsView,
        protected QOpenGLFunctions
{
    Q_OBJECT
public:
    OpenGLView( QWidget* pParent = 0 );
    virtual ~OpenGLView( void );
    void setScene( GraphicsScene* pScene );
public slots:
    bool SwitchShader( const QString& shaderFileName );
    void SetLightPos( const QVector3D& lightPos = QVector3D( ) );
protected:
    void resizeEvent( QResizeEvent* pEvent );
    void mousePressEvent( QMouseEvent* pEvent );
    void mouseReleaseEvent( QMouseEvent* pEvent );
    void mouseMoveEvent( QMouseEvent* pEvent );
    void wheelEvent( QWheelEvent* pEvent );
    void drawBackground( QPainter* pPainter, const QRectF& rect );
private:
    void InitGL( void );
    void ResizeGL( int width, int height );
    void PaintGL( void );
    void DrawAxis( void );
    bool SetupShaders( void );
    Camera          m_Camera;
    Format3DS       m_3DS;
    // 着色器
    QOpenGLShader*  m_pVertexShader;
    QOpenGLShaderProgram* m_pShaderProgram;
};

这里我们在它的成员中添加了一个摄像机,一个3ds模型实例,还有一个顶点着色器和着色器程序类。在上次的博客中讲到了在这种情况最好使用类指针而不是类成员作为数据成员,这里我索性把着色器程序类也做成了指针成员了。

由于OpenGLView类实现比较长,这里我着重说一下其中的几个函数。下面是drawBackground()函数的实现:

void OpenGLView::drawBackground( QPainter* pPainter,
                                 const QRectF& )
{
    pPainter->beginNativePainting( );
    glPushAttrib( GL_ALL_ATTRIB_BITS );
    InitGL( );
    ResizeGL( pPainter->device( )->width( ),
              pPainter->device( )->height( ) );
    PaintGL( );
    glPopAttrib( );
    pPainter->endNativePainting( );
}

为什么选择drawBackground()?因为我们想要得到一种效果,OpenGL在底层绘制,上面绘制控件,其实自从QPainter有了beginNativePainting()和endNativePainting()这两个函数,我们就可以进行纯OpenGL的绘制了。这里还要注意的是,因为绘制控件也是使用OpenGL的context,这样简单调用会让OpenGL的状态混乱,所以需要将各种状态通过glPushAttrib(GL_ALL_ATTRIB_BITS);保存起来,然后初始化我们的OpenGL状态,以及绘图,最后记得glPopAttrib();还原所有状态供2D绘制。这里就不像以往的GLWidget套路了,因为GLWidget里面的initializeGL()函数只调用一次,paintGL()函数调用多次,但是在这里,只要有刷新的消息(通过update()或repaint()触发),就必须调用InitGL()函数来进行OpenGL状态的设置,否则先前设置的所有状态都消失了。

接下来看看ResizeEvent()函数:

void OpenGLView::resizeEvent( QResizeEvent* pEvent )
{
    scene( )->setSceneRect( 0.0,
                            0.0,
                            pEvent->size( ).width( ),
                            pEvent->size( ).height( ) );
    pEvent->accept( );
}

这里由于我们已经设置了scene为GraphicsScene类的实例指针,因此scene()是非空的,我们将场景限制为view的大小,这样可以避免一些刷新的问题。

而paintGL()函数也是相当的简单。

void OpenGLView::PaintGL( void )
{
    glClear( GL_COLOR_BUFFER_BIT |
             GL_DEPTH_BUFFER_BIT );
    glPushMatrix( );
    m_Camera.Apply( );
    m_3DS.RenderGL( );
    if ( g_ShowAxis ) DrawAxis( );
    glPopMatrix( );
}

接着我向大家介绍一下GraphicsScene类:

class GraphicsScene: public QGraphicsScene
{
    Q_OBJECT
public:
    GraphicsScene( QObject* pParent = 0 );
    void SetCamera( Camera* pCamera );
signals:
    void SwitchShader( const QString& shaderFileName );
    void SetLightPos( const QVector3D& pos );
protected:
    void mousePressEvent( QGraphicsSceneMouseEvent* pEvent );
    void mouseMoveEvent( QGraphicsSceneMouseEvent* pEvent );
    void mouseReleaseEvent( QGraphicsSceneMouseEvent* pEvent );
    void wheelEvent( QGraphicsSceneWheelEvent* pEvent );
private slots:
    void Feedback( void );
private:
    // 鼠标事件需要
    QPointF         m_LastPos;
    Camera*         m_pCamera;
};

这里的GraphicsScene类保存的是来自view的Camera和一些信号以及事件的处理。在实现上也说一下它的构造函数吧。

GraphicsScene::GraphicsScene( QObject* pParent ):
    QGraphicsScene( pParent ), m_pCamera( Q_NULLPTR )
{
    ClickableTextItem* pTextItem = new ClickableTextItem( Q_NULLPTR );
    pTextItem->setPos( 10.0, 10.0 );
    pTextItem->setHtml( tr( "<font color=white>"
                            "Made By Jiangcaiyang<br>"
                            "Created in September<br>"
                            "Click for feedback."
                            "</font>" ) );
    connect( pTextItem, SIGNAL( Clicked( ) ),
             this, SLOT( Feedback( ) ) );
    addItem( pTextItem );
    ShaderOptionDialog* pDialog = new ShaderOptionDialog;
    connect( pDialog, SIGNAL( SwitchShader( const QString& ) ),
             this, SIGNAL( SwitchShader( const QString& ) ) );
    connect( pDialog, SIGNAL( SetLightPos( const QVector3D& ) ),
             this, SIGNAL( SetLightPos( const QVector3D& ) ) );
    QGraphicsProxyWidget* pProxy = addWidget( pDialog, Qt::Window | Qt::WindowTitleHint );
    pProxy->setPos( 100, 200 );
}

我们创建了一个ClickableTextItem类,它继承于QGraphicsTextItem,它被摆在左上角,显示三排可以点击的文字。随后添加了一个对话框,设置信号和槽完毕后就用代理放入场景中了。整个过程也是非常简单的。

我测试了下,整个程序在我的Ubuntu13.04下能够正常运行。只是由于显卡不同(Ubuntu下较难支持nvidia显卡,使用的是intel集显),specularOpt效果出不来。


1楼suannai03143小时前您的文章已被推荐到CSDN首页,感谢您的分享。

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
java/j2ee iis7站长之家
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3