当前位置:  编程技术>移动开发
本页文章导读:
    ▪简略实现自己的Content Provider(一)        简单实现自己的Content Provider(一) 项目中突然想用Content Provider实现跨应用操作数据的功能,虽然后来没有利用Content Provider来实现。但还是写了个简单demo程序,熟悉一下Content Provider的开发.........
    ▪ OC三拇指针的改变和要点        OC中指针的改变和要点 直接看例子!!! // // main.m // PointerPointer // // Created by Rayln Guan on 8/30/13. // Copyright (c) 2013 Rayln Guan. All rights reserved. // #import <Foundation/Foundation.h> void test1(NSStri.........
    ▪ CoreText学习(1)Base Objects of Core Text       CoreText学习(一)Base Objects of Core Text最近要做一个读入Word,PDF格式等的文件并且加以编辑的程序,本来以为使用Text Kit结合Text View来打开doc文件是完全没问题的,结果用了各种方法打开要么.........

[1]简略实现自己的Content Provider(一)
    来源: 互联网  发布时间: 2014-02-18
简单实现自己的Content Provider(一)

项目中突然想用Content Provider实现跨应用操作数据的功能,虽然后来没有利用Content Provider来实现。但还是写了个简单demo程序,熟悉一下Content Provider的开发。这篇文章只是简单记录下,下一篇文章具体解释需要注意的问题

 

两个项目,一个继承Content Provider将数据库的CRUD操作显露给其他应用,另一个项目,则是进行CRUD操作。很简单的功能。

 

-----------------------

项目1:

首先创建 DatabaseHelper

	private static String DATABASE_NAME = "db_name";
	public static String TABLE_NAME = "db_table_name";
	public static String COL_ID = "_id";
	public static String COL_TXT = "txt";

	public DatabaseHelper(Context context) {
		super(context, DATABASE_NAME, null, 1);

	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("create table if not exists " + TABLE_NAME + "(" + COL_ID
				+ " integer primary key autoincrement, " + COL_TXT + " text )");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub

		db.execSQL("drop table if exists " + TABLE_NAME);

		onCreate(db);
	}

 

然后实现 Content Provider功能

private static final String TAG = "TestContentProvider";

	private DatabaseHelper dbHelper;

	// public constants for client development
	public static final String AUTHORITY = "info.zhegui.contentprovider.provider";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
			+ "/" + DatabaseHelper.TABLE_NAME);

	// helper constants for use with the UriMatcher
	private static final int LENTITEM_LIST = 1;
	private static final int LENTITEM_ID = 2;
	private static final UriMatcher URI_MATCHER;

	/**
	 * Column and content type definitions for the LentItemsProvider.
	 */
	public static interface LentItems extends BaseColumns {
		public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
				+ "/vnd.info.zhegui.provider." + DatabaseHelper.TABLE_NAME;
		public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
				+ "/vnd.info.zhegui.provider." + DatabaseHelper.TABLE_NAME;
	}

	static {
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(AUTHORITY, DatabaseHelper.TABLE_NAME, LENTITEM_LIST);
		URI_MATCHER.addURI(AUTHORITY, DatabaseHelper.TABLE_NAME + "/#",
				LENTITEM_ID);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int rowNum = dbHelper.getWritableDatabase().delete(
				DatabaseHelper.TABLE_NAME, selection, selectionArgs);

		return rowNum;
	}

	@Override
	public String getType(Uri uri) {
		switch (URI_MATCHER.match(uri)) {
		case LENTITEM_LIST:
			return LentItems.CONTENT_TYPE;
		case LENTITEM_ID:
			return LentItems.CONTENT_ITEM_TYPE;
		default:
			throw new IllegalArgumentException("Unsupported URI: " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {

		long rowId = dbHelper.getWritableDatabase().insert(
				DatabaseHelper.TABLE_NAME, null, values);

		return Uri.parse(CONTENT_URI + "/" + rowId);
	}

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());

		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		if (URI_MATCHER.match(uri) != LENTITEM_LIST) {
			throw new IllegalArgumentException(
					"Unsupported URI for insertion: " + uri);
		}

		return dbHelper.getReadableDatabase().query(DatabaseHelper.TABLE_NAME,
				projection, selection, selectionArgs, null, null, null);
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {

		int rowNum = dbHelper.getWritableDatabase().updateWithOnConflict(
				DatabaseHelper.TABLE_NAME, values, selection, selectionArgs,
				SQLiteDatabase.CONFLICT_FAIL);

		return rowNum;
	}

 

接下来在manifest中声明

        <provider
            android:name="TestContentProvider"
            android:authorities="info.zhegui.contentprovider.provider"
            android:exported="true" />

 

ok,项目就完成了。就是这么简单!

 

-------------------------------------------------------

项目2:

只是简单调用CRUD操作,直接上代码

public static String TABLE_NAME = "db_table_name";
	public static final String AUTHORITY = "info.zhegui.contentprovider.provider";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
			+ "/" + TABLE_NAME);

	public static String COL_ID = "_id";
	public static String COL_TXT = "txt";

	public static interface LentItems extends BaseColumns {
		public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
				+ "/vnd.info.zhegui.provider." + TABLE_NAME;
		public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
				+ "/vnd.info.zhegui.provider." + TABLE_NAME;
	}

	private EditText etIccid;
	private ListView listView;

	private CustomAdapter mAdapter;
	private Handler handler;

	private List<Item> listData = new ArrayList<Item>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		handler = new Handler(this);

		etIccid = (EditText) findViewById(R.id.et);
		listView = (ListView) findViewById(R.id.listview);
		mAdapter = new CustomAdapter();
		((Button) findViewById(R.id.btn_add))
				.setOnClickListener(new View.OnClickListener() {

					@Override
					public void onClick(View v) {
						final String txt = etIccid.getEditableText().toString();
						if (!TextUtils.isEmpty(txt)) {
							new Thread() {
								public void run() {
									ContentValues values = new ContentValues();
									values.put(COL_TXT, txt);
									Uri uri = getContentResolver().insert(
											CONTENT_URI, values);
									if (uri != null) {
										getData();
									}
								}
							}.start();

						}
						etIccid.setText("");

					}
				});

		listView.setAdapter(mAdapter);

		getData();

	}

	private synchronized void getData() {
		new Thread() {
			public void run() {
				listData.clear();

				Cursor cursor = getContentResolver().query(CONTENT_URI, null,
						null, null, null);
				Log.i(TAG, "line 100 cursor:" + cursor);
				if (cursor != null) {
					while (cursor.moveToNext()) {
						long id = cursor.getLong(cursor.getColumnIndex(COL_ID));
						String str = cursor.getString(cursor
								.getColumnIndex(COL_TXT));

						listData.add(new Item(id, str));
					}
				}
				handler.sendEmptyMessage(0);
			}
		}.start();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public static class ViewHolder {
		EditText et;
		Button btnUpdate;
		Button btnDelete;
	}

	public class Item {
		long id;

		public Item(long id, String str) {
			this.id = id;
			this.txt = str;
		}

		public long getId() {
			return id;
		}

		public String getTxt() {
			return txt;
		}

		String txt;
	}

	public class CustomAdapter extends BaseAdapter {

		public CustomAdapter() {

		}

		@Override
		public int getCount() {
			return listData.size();
		}

		@Override
		public Object getItem(int position) {
			return listData.get(position);

		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			ViewHolder holder = null;

			if (convertView == null) {
				holder = new ViewHolder();
				convertView = LayoutInflater.from(MainActivity.this).inflate(
						R.layout.list_item, parent, false);
				holder.et = (EditText) convertView.findViewById(R.id.et_item);
				holder.btnUpdate = (Button) convertView
						.findViewById(R.id.btn_update);
				holder.btnDelete = (Button) convertView
						.findViewById(R.id.btn_delete);

				convertView.setTag(holder);

			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			holder.et.setText(listData.get(position).getTxt());
			holder.et.setTag("et_" + position);
			holder.btnDelete.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					// listData.remove(position);
					// mAdapter.notifyDataSetChanged();

					int rowId = getContentResolver()
							.delete(CONTENT_URI,
									COL_ID + " =?  ",
									new String[] { listData.get(position)
											.getId() + "" });
					if (rowId != 0) {
						getData();
					}

				}
			});
			holder.btnUpdate.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					String et = ((EditText) listView.findViewWithTag("et_"
							+ position)).getText().toString();
					if (!TextUtils.isEmpty(et)) {
						// listData.set(position, et);
						// mAdapter.notifyDataSetChanged();
						ContentValues values = new ContentValues();
						values.put(COL_TXT, et);
						int rowId = getContentResolver().update(
								CONTENT_URI,
								values,
								COL_ID + " =?  ",
								new String[] { listData.get(position).getId()
										+ "" });
						if (rowId != 0) {
							getData();
						}

					}
				}
			});

			return convertView;
		}
	}

	@Override
	public boolean handleMessage(Message msg) {
		mAdapter.notifyDataSetChanged();

		return false;
	}

 

 

 

附2个项目源码

 


    
[2] OC三拇指针的改变和要点
    来源: 互联网  发布时间: 2014-02-18
OC中指针的改变和要点
直接看例子!!!
//
//  main.m
//  PointerPointer
//
//  Created by Rayln Guan on 8/30/13.
//  Copyright (c) 2013 Rayln Guan. All rights reserved.
//

#import <Foundation/Foundation.h>

void test1(NSString *str){
    str = @"567";
}
void test2(NSString **str){
    *str = @"678";
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        NSString *str = @"12345";
        test1(str);
        NSLog(@"str:%@", str); //打印出12345
        
        test2(&str);
        NSLog(@"&str:%@", str); //打印出678
        
    }
    return 0;
}



    
[3] CoreText学习(1)Base Objects of Core Text
    来源: 互联网  发布时间: 2014-02-18
CoreText学习(一)Base Objects of Core Text

最近要做一个读入Word,PDF格式等的文件并且加以编辑的程序,本来以为使用Text Kit结合Text View来打开doc文件是完全没问题的,结果用了各种方法打开要么是数据是nil,要么打开的文字中很多乱码。对于Word,PDF这种格式或许必须要用底层的Core Text来做了(如果用WebView来做的话,很难对内容进行操作)。

所以接下来又要从Core Text从头学起了。首先看了Core Text Programming Guide,理解的并不算深入,但是写个博客来做个笔记吧。


Core Text是一个iOS中一个比较底层的框架,借用iOS7 Text Kit介绍视频中的一个图:


其中Core Text在Core Graphics之上,Text Kit在Core Text之上构建(UIWebView不在Text Kit之上,很多Text Kit中很棒的特性UIWebView无法使用)。

在文档中,Core Text被描述为一个高级的、底层的框架,主要用来对文本进行排版布局和字体处理。

Core Text有一个很强大的功能就是进行Character-to-glyph转换,其实之前看Text Kit的时候glyph这个词就是一个高频出现的词,个人觉得必须要分清楚character,glyph,font这些概念之间的分别。

按照个人的理解(语文不好,说错了请指出):

(1)character:字符,指一个符号,数字或者文字等。

(2)glyph:字形,对于同一套字符有不同的写法,形态或者说是样式。字形是字符的一族形态,例如Helvetica, New Roman

(3)font:字体,在字形的基础上进行的加工修饰便构成了字体,如加粗,倾斜,加颜色,改变磅数等。例如

9pt Helvetica Bold是一个字体。

回到文档来看看Character-to-glyph conversion:


对应同一个字符A,有着各种不同的形态,对应不同的字形glyph,当然同一种风格的写法便构成了一种字形。


同样地,对于f加l两个字符连起来写便又变成了一种新的写法,对应另外一种字形。

通过Core Text可以快速高效地进行字符到字形之间的转换。

使用Core Text可以直接使用Core Foundation的对象,这些对象是toll-free bridging的(一种允许某些OC类与其对应的CoreFoundation类之间可以互换使用的机制),所以无需进行特殊的对象类型转换。另外Core Text构建于Core Graphics框架之上,所以可以通过Core Graphics的方法进行高效高质量的文字描画。


接下来是Core Text的一些Base Objects。

1.Layout Objects:Framesetters, Frames, Typesetters, Lines and Glyph runs

还是先上个图吧:


其中framesetter通过attributed string对象持有文本的内容,并调用typesetter来创建line对象从而填满由CGPath所描述的区域。输出的结果是包含了一系列行对象的一个frame。

其中每一个line中对于相同属性内的一段文字使用同一个的CTRun对象去描画该段文字:


下面这张图(来自raywenderlich)更加容易理解:


其中CTRun对象会由Core Text自动生成,不需要也不应该由开发者自己去创建,所以整个程序跑起来有很多细节是开发者不用考虑的。


2.Font Objects:Fonts, Font Descriptors, Font Collections

Font Descriptor用来描述字体的特性,是Font的核心部分,Font Collections是许多个Font Descriptors的集合。


说完一大堆Core Text的基本对象后,还是写个Demo看看(主要参考了http://blog.csdn.net/andypan1314/article/details/7614469)

首先要使用Core Text框架的话,第一步是要导入CoreText.framework,然后在要使用的头文件中导入:

#import <CoreText/CoreText.h>

在使用Core Text来draw文字的时候,关键是要使用UIView中的drawRect:方法,所以先新建一个ViewController,然后新建一个UIView的子类,并将二者在视图上关联起来。

然后重写View中的drawRect:方法:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    
    // 1.创建一个字符串用来保存文本内容  CFAttributedString
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"First Core Text Demo"];
    
    
    // 2.创建一个framesetter用来管理描画文字的frame  CTFramesetter
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
    
    
    // 3.创建一个用来描画文字的路径,其区域为当前视图的bounds  CGPath
    CGMutablePathRef path = CGPathCreateMutable();
    CGRect rectForPath = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height - 20.0);
    CGPathAddRect(path, NULL, rectForPath);
    
    
    // 4.创建由framesetter管理的frame,是描画文字的一个视图范围  CTFrame
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, attrString.length), path, NULL);
    
    
    // 5.获取当前视图的上下文环境
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    
    // 6.通过context在frame中描画文字内容
    CTFrameDraw(frame, context);
    
    
    // 7.所有创建的对象必须被release
    CFRelease(frame);
    CFRelease(path);
    CFRelease(frameSetter);
}


以上代码中各个对象的创建顺序基本与Figure 1.3相同。

其中首先对NSAttributedString强制类型转换得到CFAtttributedString对象用来保存文本内容,然后创建一个CTFramesetter对象用来保存文本内容、在所管理的Frame中对文字进行布局、输出文字等,接着创建CGPath对象和CTFrame对象,二者定义了一个输出文字内容的区域。注意CTTypesetter在CTFramesetter创建时随之而生成了,不需要再手动去创建。

在基本对象创建好后,获取当前视图上下文并设置好一些仿射变换后,直接在Frame中draw就完成了文字的输出:


注意最后所有创建的Core Foundation对象都必须被释放。


还有一个大问题,draw出来的文字是倒过来的,必须要将它们倒回来。

这就涉及到仿射变换的内容了,有篇文章挺好理解的:http://hi.baidu.com/cqhg1981/item/1a527bf4bda2fb0fc6dc45aa

主要的仿射变换有下面几种:



其中translation是平移,flip是翻转,rotation是旋转,scaling是缩放,shear是错切,identity是保持不变。


再看看基本的仿射变换代码:

// 平移仿射变换:tx为x正方向上的位移量,ty为y正方向上的位移量
CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

// 缩放仿射变换:在原点的基础上进行缩放,sx为x正方向上的缩放倍数,sy为y正方向上的缩放倍数。如果缩放倍数为负数则为反向缩放
CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy);

// 旋转仿射变换:angle为旋转角度,逆时针为正,顺时针为负
CGContextRotateCTM(CGContextRef c, CGFloat angle);


在CGContextRef context =UIGraphicsGetCurrentContext();下面加上以下代码。

首先设置好初始的仿射变换矩阵(原封不动):

CGContextSetTextMatrix(context, CGAffineTransformIdentity);


然后将整个视图向右移动10.0,向下方移动整个视图的高度:

CGContextTranslateCTM(context, 10.0, self.bounds.size.height);

最后倒过来(方向放大):

CGContextScaleCTM(context, 1.0, -1.0);

Run一下:


完成了。


Core Text还有很多内容,随着我学习的深入会继续更新博客的。








    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪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