摘要: 破茧成蝶~!!! “微读”2.0正式发布,今天刚刚好是12月27号,真的很巧合,v1.0版本是11月27号发布的,刚刚好一个月时间,从中得到了很多的支持和意见,感谢大家使用我的软件,只要还有人愿意用我会不断的升级更新,希望做一个简单优秀的软件。新版体验地址微读软件:点击下载网站:http://www.app1001.com/新浪微博:@easy微读v1.0版本功能(已经上线):1、支持本地txt格式小说阅读v2.0版本功能(已经上线):1、支持本地txt格式小说阅读2、新浪微博的阅读计划(继续开发中):1、加入更多的在线内容2、加入特色内容阅读微读v2.0功能介绍这里主要先截图介绍一下2.0新阅读全文
posted @ 2011-12-28 10:02 水的右边 阅读(593) 评论(9) 编辑

我只能说“微读”2.2版本又发布了,首先还是感谢大家使用我的软件,只要还有人愿意用我会不断的升级更新,希望做一个简单优秀的软件。

新版加入了一些个性的在线内容阅读,微美图、微漫画、微美女阅读。

新版体验地址

微读软件:点击下载

网站:http://www.app1001.com/ 

新浪微博:@easy微读

 

v1.0版本功能(已经上线):

1、支持本地txt格式小说阅读

v2.0版本功能(已经上线):

1、支持本地txt格式小说阅读

2、新浪微博的阅读

v2.2版本功能(已经上线):

1、支持本地txt格式小说阅读

2、新浪微博的阅读

3、微美图阅读

4、微漫画阅读

5、微美女阅读

计划(继续开发中)

1、加入更多的在线内容

2、加入特色内容阅读

微读v2.2功能介绍

这里还是先截图介绍一下2.2新增加的新浪微博阅读功能,让大家先睹为快,有图有真相,具体的大家可以点击上面的地址下载一个安装试试了。

关于原来功能

介绍可以参看:《我的android阅读软件“微读”-做最简单的手机阅读软件》《我的android阅读软件“微读”v2.0发布,加入新浪微博的支持》

1、首页截图,现在支持的类型:txt小说、新浪微博、微美图、微漫画、微美女,新增加微美图、微漫画、微美女都需要有新浪微博账号才能阅读

 

2、微美图列表和内容页面

 

2、微美内容页面和评论页面,支持左右拖拽操作,在微漫画和微美女中也支持同样操作

  

3、微漫画列表和内容页面

 

4、微美女列表和内容页面

 

posted @ 2012-01-09 10:33 水的右边 阅读(486) 评论(4) 编辑

破茧成蝶~!!! “微读”2.0正式发布,今天刚刚好是12月27号,真的很巧合,v1.0版本是11月27号发布的,刚刚好一个月时间,从中得到了很多的支持和意见,感谢大家使用我的软件,只要还有人愿意用我会不断的升级更新,希望做一个简单优秀的软件。

新版体验地址

微读软件:点击下载

网站:http://www.app1001.com/ 

新浪微博:@easy微读

 

v1.0版本功能(已经上线):

1、支持本地txt格式小说阅读

v2.0版本功能(已经上线):

1、支持本地txt格式小说阅读

2、新浪微博的阅读

计划(继续开发中)

1、加入更多的在线内容

2、加入特色内容阅读

微读v2.0功能介绍

这里主要先截图介绍一下2.0新增加的新浪微博阅读功能,让大家先睹为快,有图有真相,具体的大家可以点击上面的地址下载一个安装试试了。

关于txt文件阅读介绍可以参看:《我的android阅读软件“微读”-做最简单的手机阅读软件》

1、首页和菜单设置页,可以添加新浪微博账号和txt书籍,支持设置代理上网

 

2、微博主页,独特的旋转菜单,可以展开可以收起,点击原型菜单进行功能切换

  

 

3、微博个人信息页面

 

4、微博个人资料页面

 

 

5、微博更多功能页面

 

6、微博详细内容浏览页面,可以直接点击展开查看评论

 

7、微博发布功能页面

 

posted @ 2011-12-28 10:02 水的右边 阅读(593) 评论(9) 编辑

今天讲一下我开发“微读”阅读软件中实现的一个类似android主界面的滑屏控件,这个滑屏在微读的主界面和看书时左右滑平翻页中都有用到,在具体的应用效果如下:
下载到手机中体验一下

微读软件:点击下载

网站:http://www.app1001.com/ 

新浪微博:@easy微读

直接效果图 ,更多内容可以参看:我的android阅读软件“微读”-做最简单的手机阅读软件

    

       实现思路,刚开始的时候我是用ViewFlipper控件来做非常的简单但是实现不了拖拽移动屏幕的效果,最终放弃决定自定义一个控件实现这样效果。

接下来我详细的解说一下我开发时写的这个实验demo,软件中用的滑屏就是由这样的代码实现的。

       首先新建一个控件类TouchPageView并且继承自ViewGroup,左右滑动换屏我的实现是在TouchPageView添加3个子view分别代表看不到的左边屏幕、可以看到的中间屏幕、看不到的右边屏幕,这样在滑屏时候就可以通过不断调整这3个view的位置实现连续不间断滑屏换屏,下面的实验中我分别把3个view设置成红色、绿色、黄色这样切换的时候可以看到明显效果,这3个view在TouchPageView的构造方法中调用init方法进行初始化:

private void init()
{
views= new ArrayList<LinearLayout>();
view1=new LinearLayout(context);
view1.setBackgroundColor(Color.YELLOW);
this.addView(view1);
TextView tv=new TextView(context);
tv.setText("测试");
view1.addView(tv);
views.add(view1);


view2=new LinearLayout(context);
view2.setBackgroundColor(Color.RED);
this.addView(view2);
views.add(view2);

view3=new LinearLayout(context);
view3.setBackgroundColor(Color.GREEN);
this.addView(view3);
views.add(view3);

final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
}

       接下来的实现是关键,重写onLayout方法对3个view的显示位置布局进行控制,通过下面的这个方法,把3个view进行水平一个跟着一个进行布局显示。

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = -1;
final int count = views.size();
//水平从左到右放置
for (int i = 0; i < count; i++) {

final View child =views.get(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
if(childLeft==-1)
{
childLeft=-childWidth;
}
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
}

}

       3个view位置放置好之后,接下来的实现实现手指在屏幕拖拽滑动时让3个view跟着手指的位置进行变化显示,这个肯定是在onTouchEvent方法中实现了,分别在MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP三个手指状态中进行控制,在下面的实现中还采用了VelocityTracker的方法对手指的滑动速度进行跟踪,这样根据滑动速度决定屏幕往哪个方向换屏,关键的代码如下:

@Override
public boolean onTouchEvent(MotionEvent ev){

if(!lock)
{
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);

final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();

switch (action) {
case MotionEvent.ACTION_DOWN://按下去
if(touchState==TOUCH_STATE_REST)

{
//记录按下去的的x坐标
lastMotionX = x;

touchState=TOUCH_STATE_MOVING;

isMoved=false;
}

break;
case MotionEvent.ACTION_MOVE://拖动时
if(touchState==TOUCH_STATE_MOVING)

{
float offsetX=x-lastMotionX;
float offsetY=y-lastMotionY;

if(isMoved)
{
lastMotionX=x;
lastMotionY=y;

final int count = views.size();
//水平从左到右放置
for (int i = 0; i < count; i++) {

final View child =views.get(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
int childLeft = child.getLeft()+(int)offsetX;
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
}
}
else if(Math.abs(offsetX)>TOUCH_SLOP||Math.abs(offsetY)>TOUCH_SLOP)
{
//移动超过阈值,则表示移动了
isMoved=true;

removeCallbacks(mLongPressRunnable);
}
}

break;
case MotionEvent.ACTION_UP://放开时
//释放了
removeCallbacks(mLongPressRunnable);


if(isMoved)
{
if(touchState==TOUCH_STATE_MOVING)
{
touchState=TOUCH_STATE_SLOWING;
int sign=0;
final VelocityTracker velocityTracker = mVelocityTracker;
//计算当前速度
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

//x方向的速度
int velocityX = (int) velocityTracker.getXVelocity();

if(velocityX > SNAP_VELOCITY)//足够的能力向左
{

sign=1;
Log.e("enough to move left", "true");
}
else if (velocityX < -SNAP_VELOCITY)//足够的能力向右
{

sign=-1;
Log.e("enough to move right", "right");
}
else
{
sign=0;
}
moveToFitView(sign);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}

}
}


break;
}
}
return true;
}

       完成手指滑的功能后,最后在手指离开屏幕的时候,让3个view滑动到合适的位置,保证当前屏幕只能看到一个完整的view另外2个view不可见,并且在滑动的过程中为了达到比较自然的效果,采用减速滑动的实现,这里是用了Handler进行间隔的减速移动效果,这样滑动起来比较舒服,其实最好的效果应该加入阻尼效果,就是让view一定程度的冲过屏幕边界然后在回弹,经过几次这样的缓减至速度为零然后最终停止,这个可以由各位自己去实现,并不难写。

int offset=0;
private void moveToFitView(int sign)
{
boolean b=swapView(sign);
if(true)
{
View view1=views.get(1);
int left=view1.getLeft();
//int offset=0;
if(left!=0)

{
offset=-1*left;
}

moveView();
}
}

FlipAnimationHandler mAnimationHandler;
int ovv=40;
private void moveView()
{
final int count = views.size();

if(offset!=0)
{
int ov=0;
if(offset>0)
{
ov=ovv;
}
else
{
ov=-1*ovv;
}
ovv=ovv-3;
if(ovv<1)
{
ovv=3;
}
if(Math.abs(offset)<Math.abs(ov))
{
ov=offset;
offset=0;

}
else
{
offset=offset-ov;
}

//水平从左到右放置
for (int i = 0; i < count; i++) {

final View child =views.get(i);
final int childWidth = child.getMeasuredWidth();
int childLeft = child.getLeft()+ov;
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}

if(mAnimationHandler==null)
{
mAnimationHandler = new FlipAnimationHandler();
}
mAnimationHandler.sleep(1);
}
else
{
ovv=40;
touchState=TOUCH_STATE_REST;
}
}

class FlipAnimationHandler extends Handler {
@Override
public void handleMessage(Message msg) {
TouchPageView.this.moveView();
}

public void sleep(long millis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), millis);
}
}

整个自定义控件核心的思路和代码就上面这些了,实现效果请参看我的微读效果。

完整的代码:

 

package xx.weidu;

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

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TouchPageView extends ViewGroup{

	private LinearLayout view1;
	private LinearLayout view2;
	private LinearLayout view3;
	

	//速度跟踪
	private VelocityTracker mVelocityTracker;
	private int mMaximumVelocity;
	
	//手势临界速度,当速度超过这个时切换到下一屏
    private static final int SNAP_VELOCITY = 100;
    
    //停止状态
	private final static int TOUCH_STATE_REST = 0;
    //滚动状态
	private final static int TOUCH_STATE_MOVING = 1;
	//减速停止状态
	private final static int TOUCH_STATE_SLOWING = 2;
	
	//当前触摸状态
	private int touchState = TOUCH_STATE_REST;
    
	private boolean lock=false;
	
	private float lastMotionX;
    private float lastMotionY;
    
	private Context context;
	private List<LinearLayout> views;
	//是否移动了
	private boolean isMoved;
	//长按的runnable
    private Runnable mLongPressRunnable;
	//移动的阈值
	private static final int TOUCH_SLOP=10;
	
    public int width;
	
	public int height;
	
	public TouchPageView(Context context) {
		super(context);
		this.context=context;
		init();
	}
	
	private void init()
	{
		views= new ArrayList<LinearLayout>();
		view1=new LinearLayout(context);
		view1.setBackgroundColor(Color.YELLOW);
		this.addView(view1);
		TextView tv=new TextView(context);
		tv.setText("测试");
		view1.addView(tv);
		views.add(view1);
		
		
		view2=new LinearLayout(context);
		view2.setBackgroundColor(Color.RED);
		this.addView(view2);
		views.add(view2);
		
		view3=new LinearLayout(context);
		view3.setBackgroundColor(Color.GREEN);
		this.addView(view3);
		views.add(view3);
		
		final ViewConfiguration configuration = ViewConfiguration.get(getContext());
		mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
	}
	
	
	@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    	super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int count = views.size();
        for (int i = 0; i < count; i++) {
            final View child =views.get(i);
            child.measure(widthMeasureSpec,heightMeasureSpec);
        }
        
        int finalWidth, finalHeight;
		finalWidth = measureWidth(widthMeasureSpec);
		finalHeight = measureHeight(heightMeasureSpec);

        this.width=finalWidth;
		this.height=finalHeight;

	}
	
	private int measureWidth(int measureSpec) {
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		if (specMode == MeasureSpec.EXACTLY) {
			result = specSize;
		} else {
			result = specSize;
		}

		return result;
	}
	
	private int measureHeight(int measureSpec) {
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		if (specMode == MeasureSpec.EXACTLY) {
			result = specSize;
		} else {
			result = specSize;
		}
		return result;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childLeft = -1;
        final int count = views.size();
        //水平从左到右放置
        for (int i = 0; i < count; i++) {
            final View child =views.get(i);
            if (child.getVisibility() != View.GONE) {
                final int childWidth = child.getMeasuredWidth();
                if(childLeft==-1)
                {
                	childLeft=-childWidth;
                }
                child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
                childLeft += childWidth;
            }
        }
		
	}
	
	//绘制子元素
    @Override
	protected void onDraw(Canvas canvas) {
    	//水平从左到右放置
    	int count = views.size();
        for (int i = 0; i < count; i++) {
            View child =views.get(i);
            drawChild(canvas, child, getDrawingTime());
        }
    }

	@Override
    public boolean onTouchEvent(MotionEvent ev){
		
		if(!lock)
		{
			if (mVelocityTracker == null) {
	            mVelocityTracker = VelocityTracker.obtain();
	        }
	        mVelocityTracker.addMovement(ev);
	        
			final int action = ev.getAction();
	        final float x = ev.getX();
	        final float y = ev.getY();
	        
	        switch (action) {
	        case MotionEvent.ACTION_DOWN://按下去
	        	if(touchState==TOUCH_STATE_REST)
	        	{
	        		//记录按下去的的x坐标
	                lastMotionX = x;
	                touchState=TOUCH_STATE_MOVING;
	                
	                isMoved=false;
	        	}
	        	
	        	break;
	        case MotionEvent.ACTION_MOVE://拖动时
	        	if(touchState==TOUCH_STATE_MOVING)
	        	{
	        		float offsetX=x-lastMotionX;
	        		float offsetY=y-lastMotionY;
	        		
	        		if(isMoved)
	        		{
	        			lastMotionX=x;
		            	lastMotionY=y;

		            	final int count = views.size();
		                //水平从左到右放置
		                for (int i = 0; i < count; i++) {
		                    final View child =views.get(i);
		                    if (child.getVisibility() != View.GONE) {
		                        final int childWidth = child.getMeasuredWidth();
		                        int childLeft = child.getLeft()+(int)offsetX;
		                        child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
		                        childLeft += childWidth;
		                    }
		                }
	        		}
	        		else if(Math.abs(offsetX)>TOUCH_SLOP||Math.abs(offsetY)>TOUCH_SLOP)
	        		{
	        			//移动超过阈值,则表示移动了
						isMoved=true;
						removeCallbacks(mLongPressRunnable);
	        		}
	        	}
	        	
	        	break;
	        case MotionEvent.ACTION_UP://放开时
	        	//释放了
				removeCallbacks(mLongPressRunnable);
				
				if(isMoved)
				{
					if(touchState==TOUCH_STATE_MOVING)
		        	{
		        		touchState=TOUCH_STATE_SLOWING;
		        		int sign=0;
		            	final VelocityTracker velocityTracker = mVelocityTracker;
		                //计算当前速度
		                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
		                //x方向的速度
		                int velocityX = (int) velocityTracker.getXVelocity();
		                if(velocityX > SNAP_VELOCITY)//足够的能力向左
		                {
		                	sign=1;
		                	Log.e("enough to move left", "true");
		                }
		                else if (velocityX < -SNAP_VELOCITY)//足够的能力向右
		                {
		                	sign=-1;
		                	Log.e("enough to move right", "right");
		                }
		                else
		                {
		                	sign=0;
		                }
		            	moveToFitView(sign);
		            	if (mVelocityTracker != null) {
		                    mVelocityTracker.recycle();
		                    mVelocityTracker = null;
		                }
		            	
		        	}
				}
	        	
	        	
	        	break;
	        }
		}
		return true;
	}
	
	int offset=0;
	private void moveToFitView(int sign)
	{
		boolean b=swapView(sign);
		if(true)
		{
			View view1=views.get(1);
			int left=view1.getLeft();
			//int offset=0;
			if(left!=0)
			{
				offset=-1*left;
			}
			
			moveView();
		}
	}
	
	FlipAnimationHandler mAnimationHandler;
	int ovv=40;
	private void moveView()
	{
		final int count = views.size();
		
		if(offset!=0)
		{
			int ov=0;
			if(offset>0)
			{
			    ov=ovv; 
			}
			else
			{
				ov=-1*ovv;
			}
			ovv=ovv-3;
			if(ovv<1)
		    {
		    	ovv=3;
		    }
			if(Math.abs(offset)<Math.abs(ov))
			{
				ov=offset;
				offset=0;
				
			}
			else
			{
				offset=offset-ov;
			}
			
			//水平从左到右放置
			for (int i = 0; i < count; i++) {
				final View child =views.get(i);
				final int childWidth = child.getMeasuredWidth();
				int childLeft = child.getLeft()+ov;
				child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
				childLeft += childWidth;
			}
			
			if(mAnimationHandler==null)
			{
				mAnimationHandler = new FlipAnimationHandler();
			}
			mAnimationHandler.sleep(1);
		}
		else
		{
			ovv=40;
			touchState=TOUCH_STATE_REST;
		}
	}
	
	class FlipAnimationHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			TouchPageView.this.moveView();
		}

		public void sleep(long millis) {
			this.removeMessages(0);
			sendMessageDelayed(obtainMessage(0), millis);
		}
	}
	
	private boolean swapView(int sign)
	{
		boolean b=false;
		if(sign==-1)//向左
    	{
    		View view0=views.get(0);
    		if(view0.getLeft()<=-1*view0.getMeasuredWidth())
    		{
    			swapViewIndex(sign);
    			
    			View view2=views.get(1);
    			View view3=views.get(2);
    			int childWidth=view2.getMeasuredWidth();
    			int childLeft=view2.getLeft()+childWidth;
    			view3.layout(childLeft, 0, childLeft + view3.getMeasuredWidth(), view3.getMeasuredHeight());
    			b=true;
    		}
    	}
    	else if(sign==1)//向右
    	{
    		View view3=views.get(2);
    		if(view3.getLeft()>view3.getMeasuredWidth())
    		{
    			swapViewIndex(sign);
    			
    			View view1=views.get(0);
    			View view2=views.get(1);
    			int childRight=view2.getLeft();
    			int childLeft=childRight-view1.getMeasuredWidth();
    			view1.layout(childLeft, 0, childRight, view1.getMeasuredHeight());
    			b=true;
    		}
    	}
		
		return b;
	}
	
	private void swapViewIndex(int sign)
	{
		if(sign==-1)//向左
    	{
			LinearLayout v=views.remove(0);
			views.add(v);
    	}
    	else if(sign==1)//向右
    	{
    		LinearLayout v=views.remove(views.size()-1);
    		views.add(0, v);
    	}
	}
}

  

posted @ 2011-11-28 21:07 水的右边 阅读(2217) 评论(9) 编辑

我的android阅读软件“微读”发布,从开始设计到v1.0发布前后将近6周的时间,现在发布出来请大家提提意见,扔砖、砸鸡蛋、献花都可以,请尽情的评论。万分的感谢每一个留言的人,我的目标是做一个最最简单的阅读软件,虽然还差很远但是会持续的升级改进希望有一天有人说这个好用简单。还有一句广告:中国的法律都是.txt文件,不是.exe文件——来自猫扑,所以我这个很有用,真的很有用,很支持txt!!~~~

软件:点击下载

网站:http://www.app1001.com/ 

新浪微博:@easy微读

软件截图

1、软件主页,这个是仿android主屏的实现,可以通过拖拽换屏。

2、在线升级支持,当有新功能推出时可以直接在线更新

 

3、针对某本书籍的管理菜单窗口,长按某本书时出现,对某本书籍实现阅读、删除、书签等功能。

4、主页菜单项,软件的一些常规功能和信息。

5、添加电子书功能,目前支持本机的txt文件其他的正在开发中

 

6、电子书阅读界面,仿真翻页模式。

7、电子书阅读界面,平移拖拽翻页模式。

8、阅读设置菜单功能。

9、阅读设置主题背景功能。

10、阅读设置亮度功能。

11、阅读设置字体功能,包括字号和行间距。

12、阅读翻页方式设置。

13、阅读书籍功能。

14、阅读页面跳转功能,可以任意拖拽阅读进度条。

15、阅读编码设置功能。

16、意见反馈功能,非常欢迎大家通过这个功能给我留言反馈。


posted @ 2011-11-27 21:20 水的右边 阅读(939) 评论(8) 编辑
      在上一篇中我们完成账号的添加的功能,本篇就实现账号删除的功能,完成的具体效果看上(图5),当点击删除按钮的时候出现一个弹出对话框显示是否删除当前默认选择的用户,这个显示功能跟上一篇的添加几乎没有什么区别了,同样这里的实现依旧是基于自定义组件UIDialogWindow。当进一步点击确定按钮时,从Sqlite库中把当前选中的账号从表中删除,然后更新默认选择账号,从剩下的用账号录中选择第一个账号作为默认选中,如果剩下的账号记录已经为空那么页面跳转到前面实现的用户授权功能页面引导用户重新进行用户授权操作。如果点击的是取消按钮那么就关闭弹出对话框什么也不进行操作。   
      一、首先按照UIDialogWindow的用法先新建名为DelConfirmViewController的UIViewController subclass类型的类文件,新进的时候记得勾上With XIB user interface选项。
      二、打开上一步新建的DelConfirmViewController.h文件,声明一个UITextView用来显示文字和两个UIButton按钮(确定按钮和取消按钮),delegate和onClick就不用说了,前面提到好几次了,还有确定按钮事件和取消按钮事件。具体代码如下:
#import <UIKit/UIKit.h>
#import "Global.h"

@interface DelConfirmViewController : UIViewController {

id delegate;
SEL onClick;

IBOutlet UITextView
*textView;
IBOutlet UIButton
*okBtn;
IBOutlet UIButton
*cancelBtn;
}

@property (nonatomic,retain)IBOutlet UITextView
*textView;
@property (nonatomic,retain)IBOutlet UIButton
*okBtn;
@property (nonatomic,retain)IBOutlet UIButton
*cancelBtn;

-(void)setDelegate:(id)aDelegate onClick:(SEL)aOnClick;
-(IBAction)okDel:(id)sender;
-(IBAction)cancelDel:(id)sender;

@end
      三、双击DelConfirmViewController.xib文件,在IB中打开从Library中拖相应的组件到View上并且设置相应的属性,还需要适当的设置view的尺寸大小以及view背景透明,具体如下图:
完成布局后还需要完成相应的连接工作了,具体如下图:
     四、完成DelConfirmViewController.xib设计后打开DelConfirmViewController.m完成如下代码:
-(void)setDelegate:(id)aDelegate onClick:(SEL)aOnClick
{
delegate=aDelegate;
onClick
=aOnClick;

}

-(IBAction)okDel:(id)sender
{
if (delegate) {
[
delegate performSelector:onClick withObject:@"ok"] ;
}
}

-(IBAction)cancelDel:(id)sender
{
if (delegate) {
[
delegate performSelector:onClick withObject:@"cancel"] ;
}
}
-(void)setDelegate:(id)aDelegate onClick:(SEL)aOnClick
{
delegate=aDelegate;
onClick
=aOnClick;

}

-(IBAction)okDel:(id)sender
{
if (delegate) {
[
delegate performSelector:onClick withObject:@"ok"] ;
}
}

-(IBAction)cancelDel:(id)sender
{
if (delegate) {
[
delegate performSelector:onClick withObject:@"cancel"] ;
}
}
     五、接下来就是在LoginViewController调用DelConfirmViewController进行显示,首先在LoginViewController.h添加声明DelConfirmViewController。接下来点击删除按钮调用DelConfirmViewController进行显示的代码已经在前面一篇的步骤六中完成了,有没有发现到这里为止跟前面的一片几乎一模一样了没有什么区别。
     六、接下来开始就是不同的地方了,点击删除按钮后调用[self showDelConfirm],现在完成showDelConfirm方法代码如下:
//显示删除帐号确认框
-(void)showDelConfirm
{
delConfirmViewController
=[[DelConfirmViewController alloc] init];

dialog
=[[UIDialogWindow alloc]initWithView:delConfirmViewController.view];
[delConfirmViewController setDelegate:self onClick:@selector(confirmDel:)];
NSString
*msg=[NSString stringWithFormat:@"您确定要删除名为“%@”的帐号?",selectViewController.nameLabel.text];
[[delConfirmViewController textView] setText:msg];
[dialog show];

}
     七、在上面的代码中为确定按钮设置了事件方法confirmDel,代码如下:
//确认删除帐号
-(void)confirmDel:(NSString *)txt
{
[[[[UIApplication sharedApplication] windows] objectAtIndex:
0] makeKeyAndVisible];

[dialog close];
if (txt==@"ok") {
Sqlite
*sqlite=[[Sqlite alloc] init];
if([sqlite delUser:selectViewController.nameLabel.text])
{
[self showUserInfo];
}
}
}
上面的方法中调用了Sqlite中的delUser方法从数据库中把选中的账号,删除完成后调用showUserInfo方法更新账号显示,这个方法前面的文章中已经提供了。
到处本篇的功能也就完成了,请继续关注下一篇。
posted @ 2011-06-14 12:34 水的右边 阅读(2982) 评论(11) 编辑
摘要: 本篇将在上一篇的基础上完成账号的添加的功能,这个功能都相对比较简单看上(图4),点击添加按钮的时候出现一个弹出对话框,这个对话框的实现我们已经在前面的(iphone开发我的新浪微博客户端-用户登录自定义弹出窗口篇(1.2))和(iphone开发我的新浪微博客户端-用户登录OAuth授权认证篇(1.3))这两篇博客中已经讲过弹出窗组件的定义和使用了,这里的实现依旧是基于自定义组件UIDialogWindow。 一、这个功能其实除了弹出提示窗口没有任何其他需要多做的功能,因为当点击弹出窗口的开始按钮进行账号添加的时候其实就是调用前面的(iphone开发我的新浪微博客户端-用户登录OAuth授权认.阅读全文
posted @ 2011-06-06 19:21 水的右边 阅读(2423) 评论(11) 编辑
摘要: 本篇在上一篇的基础上完成如上(图2)所示的用户登录等待功能,首先说说这个页面功能的由来,这个就是当检查sqlite库中已经存在用户账号的时候从表中把用户记录查询出来,然后从NSUserDefaults中获取上一次登录的账号,如果查询出来的用户记录中包含上一次登录的账号,那么就把这个账号作为默认显示账号,如果没有就取用户记录中的第一个账号作为默认显示账号,上一篇中当用户完成OAuth认证把账号信息保存到sqlite库后也是显示这个页面功能。 先来看看UI是怎么实现了,看上图这个界面包含用户头像小图标、用户名称、3个功能按钮(添加、切换、删除)这三部分元素,我的做法是把这三部分元素添加到一个单独.阅读全文
posted @ 2011-06-04 23:26 水的右边 阅读(2399) 评论(0) 编辑
摘要: 在上一篇中,我们已经完成了UIDialogWindow自定义弹出窗口组件,本篇接下来完成用户的OAuth授权认证功能,完成后效果如上图。 一、新建名为LoginViewController的UIViewController subclass类型的类文件,新进的时候记得勾上With XIB user interface选项.接下来我们要把这个ViewController添加到window进行显示,继续往下做。 二、打开xcode自动创建的MinBlog4SinaAppDelegate.h文件,添加如下代码:#import <UIKit/UIKit.h>@class LoginView阅读全文
posted @ 2011-05-31 22:17 水的右边 阅读(4749) 评论(14) 编辑
摘要: 本篇的目的是开发一个自定义的弹出对话窗口组件,就是上面图6中半透明的信息提示窗口,其实系统类库中已经有UIActionSheet、UIAlertView能做到这样的功能组件,但是显示外观不怎么美观而且跟我的这个设计不怎么配,同时这2个组件的外观自定义性很差几乎改变不了显示外观,所以决定自己开发一个组件。实现的思路是这样的,做一个继承自UIWindow组件的组件的对象,这样这个组件也就是一个UIWindow了然后在这个UIWindow中添加相应的半透明View达到显示效果的目的,当我们需要显示弹出窗口只需要把这个UIWindow设置为主显示窗口即可,比如执行代码:[self makeKeyAn.阅读全文
posted @ 2011-05-30 21:34 水的右边 阅读(3867) 评论(0) 编辑
摘要: 首先说一下我这个的实现思路,登录支持多个账号,也就是说可以保存多个微博账号登录的时候选择其中一个登录。多个账号信息保存在sqlite的数据库中,每一个账号信息就是一条记录, 当用户启动微博客户端的时候去取保存在sqlite数据库中的账号记录信息,然后把这些在界面中以列表的形式展示出来,用户可以点击其中的一个账号进入微博,如果如果启动微博客户端的时候检查到sqlite数据库中一个账号都没有的时候,程序自动显示用户授权认证页面,本客户端是基于oauth认证实现的,所以使用新微博账号前需要进行授权认证,一个账号只需要第一次做一下授权认证然后会把user_id、Access Token和Access.阅读全文
posted @ 2011-05-29 13:09 水的右边 阅读(4808) 评论(1) 编辑
摘要: 动手开发一个iphone上的微博客户端,虽然已经有很多很不错的客户端了,但是还是想重复造一下轮子,主要的目的就是练手,本项目的练习意义更加多一些,首先我object-c是新学的,iphone开发也是新学的,连Mac使用都是新学的,从写第一个hello world已经有段时间了,但是做实实在在的一个项目难免有很多不足了但是还是想把开发过程写成随笔。 我的开发环境:Mac OS X 10.6.6 + Xcode 3.2.5 首先我完成了一个超小型新浪微博客户端的sdk,并没有直接使用新浪提供的sdk,主要是本着学习的目的,真真正正的了解实现的原理,所以建议各位自己去实现一下自己的sdk,我把我实.阅读全文
posted @ 2011-05-28 21:39 水的右边 阅读(3415) 评论(6) 编辑
摘要: 前面的文章的OAuth认证过程在获取oauth_verifier码是是通过调用android系统带的浏览器进行用户授权认证的, 具体见:android开发我的新浪微博客户端-用户授权页面功能篇(3.2)。 当初的实现是这样: 1、首先在AndroidManifest.xml中配置给AuthorizeActivity添加如下配置<data android:scheme="myapp" android:host="AuthorizeActivity" /> ,这样在浏览器中通过地址myapp://AuthorizeActivity启动Author阅读全文
posted @ 2011-04-30 18:16 水的右边 阅读(10478) 评论(99) 编辑
摘要: 做iphone开发首先第一件就是得知道iphone程序的生命周期,说白点就是当点击程序图标启动程序开始到退出程序整个使用运行过程中底下的代码都发生了什么,只有理解了这个才能游刃有余的掌握Iphone程序的开发,否则在写程序的时候有点浑浑僵僵不知所以然的感觉。首先忘记Xcode给我们生成的代码模板,忘记xib忘记ib,我们亲自一行一行来写一个HelloWorld程序,虽然真正开发项目的时候并不需要这样做Xcode模板和ib都会为我们做好这些打杂的事情,但是现在完全由我们自己来写,放心这个程序是个非常的简单的HelloWorld 程序,代码也很少总共加起来不过10几行。 在这之前我们先来看看ob.阅读全文
posted @ 2011-03-20 10:08 水的右边 阅读(4405) 评论(9) 编辑
摘要: 在我的博客里最多的网友提问都是跟OAuth有关的,这个确实存在比较多的问题,很多都是卡在这一步。鉴于这个原因花了点时间写了个完整的新浪微博客户端android版OAuth认证示例,本代码只是功能实现示例,没有考虑程序的健壮性等方面,请自己动手完善了。但是能保证运行起来并且OAuth认证成功获取到uerId、userKey、userSecret。具体的原理实现看:android开发我的新浪微博客户端-OAuth篇(2.1)这里就不废话了,直接提供工程源文件下载:OAuth4Sina.rar下载工程文件后请修改源代码中这2行:String consumerKey="填上你自己的"阅读全文
posted @ 2011-03-13 21:20 水的右边 阅读(8712) 评论(17) 编辑
摘要: 在阅读微博的功能篇中,如果微博包含了图片就会在微博正文下面显示该张图片,但是这个图片只是张缩略图,这样就需要提供一个能放大缩小查看这张图片的功能,当点击正文中的缩略图的时候显示一个简单的图片浏览器功能,提供图片的放大、缩小、拖拽操作方便用户查看图片,同时也提供保存图片到手机的功能。本功能的UI比较简单就不单独分篇讲了,具体的实现效果如上图。 新建ImageActivity.java作为图片浏览Activity,在res/layout下新建image.xml的Layout作为图片浏览的布局文件,image.xml布局代码很简单了就不详细解释了直接贴代码:<?xmlversion="阅读全文
posted @ 2011-03-02 19:58 水的右边 阅读(6587) 评论(46) 编辑