当前位置:  编程技术>移动开发
本页文章导读:
    ▪TabActivity中的Tab标签详细设立        TabActivity中的Tab标签详细设置   参考链接: http://www.iteye.com/topic/602737 这个写的很不错,我是跟着一步步写下来的,不过到最后也遇到了麻烦,就是不能将Tab标签的文字和图片分开,始终是重.........
    ▪ Activity小品文        Activity小品 Activity小品 一、程序效果 1.程序窗口中有一个按钮Button和TextView,我们可以通过写过代码修改该Button和TextView上便签 二、代码编写和解析 1.在HelloWorld程序(Android版HelloWorld.........
    ▪ 内存泄漏调试心得分享       内存泄漏调试经验分享 (一 )  查询数据库没有关闭游标 描述:     程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor 后没有关闭的情况。如果我们的查询结果集比较小.........

[1]TabActivity中的Tab标签详细设立
    来源: 互联网  发布时间: 2014-02-18
TabActivity中的Tab标签详细设置

 

参考链接:

http://www.iteye.com/topic/602737

这个写的很不错,我是跟着一步步写下来的,不过到最后也遇到了麻烦,就是不能将Tab标签的文字和图片分开,始终是重合的,而且每个具体的代码,还是搞了许久才出来,故而分享之,希望能给大家带来方便,也谢谢下面的高人,呵呵!

http://www.youmi.net/bbs/thread-102-1-4.html

这个和上面的代码是一样的,不过代码不全,对于初学者来说,考验的时候来了,完善就是提高的过程,不要怕麻烦!

下面就根据上面的参考自己写的,当然大部分是相同的,不过有详细的注释,完整的代码

如果有什么不明白就留言吧!呵呵

首先结果图:

图1:

图2:



 图3:


当然界面没有前面的仁兄好看,我是讲究实用,美化需要自己慢慢做了

呵呵

 

下面直接代码:

 

package com.woclub.tabactivitytest;


import android.app.TabActivity;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.TabHost.OnTabChangeListener;

/**
 * 总结:在设置Tab的布局的时候首先需要newTabSpec再在其设置setIndicator(Tab名字,Tab的图标),
 * 尤其需要注意setContent(),它有三种使用方法setContent(int)它是直接在布局文件中设置其布局,
 * setContent(Intent)可以用Intent指定一个Activity,
 * setContent(TabContentFactory)可以用一个类来指定其布局的方式
 * @author Administrator
 *
 */
public class MainActivity extends TabActivity {
	
	private static final String Tab1 = "Tab1";
	private static final String Tab2 = "Tab2";
	private static final String Tab3 = "Tab3";
	private static final String Tab4 = "Tab4";
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        
      //1得到TabHost对象,正对TabActivity的操作通常都有这个对象完成
        final TabHost tabHost = this.getTabHost();
        final TabWidget tabWidget = tabHost.getTabWidget();
        
      //2生成一个Intent对象,该对象指向一个Activity,当然现在例子比较简单就没有绑定其他的Activity故而不用
      //3生成一个TabSpec对象,这个对象代表了一个Tab页
        TabHost.TabSpec tabSpec = tabHost.newTabSpec(Tab1); 
      //设置该页的indicator(指示器)设置该Tab页的名字和图标,以及布局
        tabSpec.setIndicator(composeLayout("爽哉", R.drawable.coke))
        .setContent(R.id.view1);
      //4将设置好的TabSpec对象添加到TabHost当中
        tabHost.addTab(tabSpec);
        
        //第二个Tab
        tabHost.addTab(tabHost.newTabSpec(Tab2).setIndicator(composeLayout("安逸", R.drawable.coke))
        		.setContent(R.id.view2));
        
      //第三个Tab
        tabHost.addTab(tabHost.newTabSpec(Tab3).setIndicator(composeLayout("开心", R.drawable.coke))
        		.setContent(R.id.view3));
      //第四个Tab
        tabHost.addTab(tabHost.newTabSpec(Tab4).setIndicator(composeLayout("说明", R.drawable.coke))
        		.setContent(R.id.view4));
        
 //setContent(TabContentFactory)可以用一个类来指定其布局的方式,前三个都是用的setContent(int)方式
 //        CustomLayout custom = new CustomLayout(this);
//        tabHost.addTab(tabHost.newTabSpec(Tab4).setIndicator("Tab4", getResources()
//        		.getDrawable(R.drawable.icon))
//        		.setContent(custom));
//*****************************这是对Tab标签本身的设置*******************************************
        int width =45;
        int height =48;
        for(int i = 0; i < tabWidget.getChildCount(); i++)
        {
            //设置高度、宽度,不过宽度由于设置为fill_parent,在此对它没效果
            tabWidget.getChildAt(i).getLayoutParams().height = height;
            tabWidget.getChildAt(i).getLayoutParams().width = width;
             /**
              * 下面是设置Tab的背景,可以是颜色,背景图片等
              */
             View v = tabWidget.getChildAt(i);
			if (tabHost.getCurrentTab() == i) {
				v.setBackgroundColor(Color.GREEN);
				//在这里最好自己设置一个图片作为背景更好
				//v.setBackgroundDrawable(getResources().getDrawable(R.drawable.chat));
			} else {
				v.setBackgroundColor(Color.GRAY);
			}
        }
        
//************************************************************************************
        //设置Tab变换时的监听事件
        tabHost.setOnTabChangedListener(new OnTabChangeListener() {
			
			@Override
			public void onTabChanged(String tabId) {
				// TODO Auto-generated method stub
				//当点击tab选项卡的时候,更改当前的背景
				for(int i = 0; i < tabWidget.getChildCount(); i++)
				{
				View v = tabWidget.getChildAt(i);
				if (tabHost.getCurrentTab() == i) {
					v.setBackgroundColor(Color.GREEN);
				} else {
					//这里最后需要和上面的设置保持一致,也可以用图片作为背景最好
					v.setBackgroundColor(Color.GRAY);
				}
				}
			}
		});
        
    }
//#################################################################这是设置TabWidget的布局
	/**
	 * 这个设置Tab标签本身的布局,需要TextView和ImageView不能重合
	 * s:是文本显示的内容
	 * i:是ImageView的图片位置
	 * 将它设置到setIndicator(composeLayout("开心", R.drawable.coke))中
	 */
	public View composeLayout(String s, int i){
		Log.e("Error", "composeLayout");
    	LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        
        TextView tv = new TextView(this);
        tv.setGravity(Gravity.CENTER);
        tv.setSingleLine(true);
        tv.setText(s);
        tv.setTextColor(Color.RED);
        layout.addView(tv, 
        		new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        
        ImageView iv = new ImageView(this);
        iv.setImageResource(i);
        layout.addView(iv, 
        		new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        return layout;
    }
	//#################################################################
    
}

 
 我都有详细的注释,估计大家都能看懂的,有些地方给了提示,扩展的需要就需要自己去完成了

下面是一个两个布局文件

一个是在layout中设置:

 

<?xml version="1.0" encoding="utf-8"?>
<!-- 
一个典型的标签Activity  是由2 部分构成的 且其id都有规定 即: 
* TabWidget 用于展示标签页 id=tabs 
* FrameLayout 用于展示隶属于各个标签的具体布局 id=tabconten
* TabHost 用于整个Tab布局 id=TabHost
还需注意要将Tab显示在最下面就需要这只LinearLayout时用Bottom
-->
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@android:id/tabhost"
		android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	>
	<LinearLayout
	    android:orientation="vertical"
	    android:gravity="bottom"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent">	
		<FrameLayout
			android:id="@android:id/tabcontent"  
    		android:layout_width="fill_parent"     
    		android:layout_height="200dip" >
			<RelativeLayout
				android:id="@+id/view1"
				android:orientation="vertical"
				android:layout_width="fill_parent"
				android:layout_height="fill_parent">
				<TextView
				android:id="@+id/text1"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:text="需要光临第一个Tab"/>
				<ImageView
					android:id="@+id/image1"
					android:layout_height="wrap_content"
					android:layout_below="@id/text1"
					android:layout_width="wrap_content"
					android:src="/blog_article/@drawable/icon/index.html"
					/>	
			</RelativeLayout>
			
			<TextView
				android:id="@+id/view2"
				android:layout_width="fill_parent"
				android:layout_height="fill_parent"
				android:text="需要光临第二个Tab"/>
			<TextView
				android:id="@+id/view3"
				android:layout_width="fill_parent"
				android:layout_height="fill_parent"
				android:text="需要光临第三个Tab"/>
			<TextView
				android:id="@+id/view4"
				android:layout_width="fill_parent"
				android:layout_height="fill_parent"
				
				/>
		</FrameLayout>
		<TabWidget
			android:id="@android:id/tabs"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content">
		</TabWidget>
	</LinearLayout>
</TabHost>

 还有一个在类中设置,设置都差不多,在此类中设置只是针对每个Tab页面的设置

 

package com.woclub.tabactivitytest;
import android.app.Activity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.TextView;
/**
 * 此类的功能是设置每个Tab标签的布局方式
 * 使用方法
 * CustomLayout ct = new CustomLayout(this);  
 * tHost.addTab(tHost.newTabSpec(Tab4).setIndicator("Tab 4").setContent(ct)); 
 * @author Administrator
 *
 */
public class CustomLayout implements TabHost.TabContentFactory{

	private Activity myActivity;
	private LayoutInflater layoutHelper;//用于实例化布局
	private LinearLayout layout;
	//构造函数,从外面传递参数Activity
	public CustomLayout(Activity myActivity)
	{
		this.myActivity = myActivity;
		//通过getLayoutInflater从Activity中得到一个实例化的LayoutInflater
		layoutHelper = myActivity.getLayoutInflater();
	}
	/**
	 * 根据不同的Tab创建不同的视图
	 */
	@Override
	public View createTabContent(String tag) {
		// TODO Auto-generated method stub
		return addCustomView(tag);
	}
	
	/**
	 * 根据Tab的id设置不同Tab的view
	 * 这是普通的设置方式,设置每个Tab的布局
	 * @param id
	 * @return
	 */
	private View addCustomView(String id)
	{
		layout = new LinearLayout(myActivity);
		layout.setOrientation(LinearLayout.HORIZONTAL);

		if(id.equals("Tab1"))
		{
			ImageView iv = new ImageView(myActivity);
			iv.setImageResource(R.drawable.chat);
			//设置layout的布局,将一个ImageView添加到其中,并设置ImageView的布局格式,addView的第二个参数是设置ImageView的width和Height
			layout.addView(iv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
		}
		else if(id.equals("Tab2"))
		{
			//第一个控件,注意每添加一个空间都需要用addView添加到layout中
			EditText edit = new EditText(myActivity);
			layout.addView(edit, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			//第二个控件
			Button button = new Button(myActivity);
			button.setText("确定");
			button.setWidth(100);
			layout.addView(button, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			//第三个控件
			RadioGroup rGroup = new RadioGroup(myActivity);  
            rGroup.setOrientation(LinearLayout.HORIZONTAL);  
            RadioButton radio1 = new RadioButton(myActivity);  
            radio1.setText("Radio A");  
            rGroup.addView(radio1);  
            RadioButton radio2 = new RadioButton(myActivity);  
            radio2.setText("Radio B");  
            rGroup.addView(radio2);  
              
            layout.addView(rGroup,  
                    new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));  
		}
		else if(id.equals("Tab3"))
		{
			TextView text = new TextView(myActivity);
			text.setText("the third TextView");
			text.setGravity(Gravity.CENTER);
			layout.addView(text);
		}
		else if(id.equals("Tab4"))
		{
			LinearLayout.LayoutParams param3 =  
                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);  
             //在这里面又引用了布局文件来设置控件
            layout.addView(layoutHelper.inflate(R.layout.hello, null),param3);
		}
		return layout;
	}
	


}

 好了,该说的都在代码中说明了

希望大家喜欢,做的粗糙,就由大家去改进吧!

呵呵!

欢迎大家的讨论

 


    
[2] Activity小品文
    来源: 互联网  发布时间: 2014-02-18
Activity小品

Activity小品

一、程序效果

1.程序窗口中有一个按钮Button和TextView,我们可以通过写过代码修改该Button和TextView上便签

二、代码编写和解析

1.在HelloWorld程序(Android版HelloWorld附件)基础上

2.编写layout包下的main.xml文件,主要是添加Button控件和为控件指定id

main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <!--
    android:id 为控件指定id 使用:@+id/控件名
    android:layout_width 指定控件的宽
    android:layout_height 指定控件的长
    fill_parent:填充父控件的宽度,高度,即宽度,高度父控件一样
    wrap_content:利用所包裹的内容填充,即内容多大控件多大
      -->
<TextView  
	android:id="@+id/myTextView"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
<Button
	android:id="@+id/myButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
/>
</LinearLayout>
 

3.编写自动生成的Activity类,主要是通过id取得控件并对控件进行一些操作

 

 

package linys.activity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class ActivityDemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //根据id取得控件
        TextView textView=(TextView)findViewById(R.id.myTextView);
        Button button=(Button)findViewById(R.id.myButton);
        //对控件上的便签进行修改
        textView.setText("textView");
        button.setText("button"+"\n"+"text");//wrap_content效果
    }
}
 


三、程序解析

1. Activity可以看作是一个控制器,控制着窗体的布局的加载以及窗体上控件的修改,和界面与业务程序间的调用

        2.创建Activity类时注意的:

            1)继承Activity

            2)重写OnCreate方法

            3)在AndroidMainfest.xml中配置

 

 


    
[3] 内存泄漏调试心得分享
    来源: 互联网  发布时间: 2014-02-18
内存泄漏调试经验分享

(一 )  查询数据库没有关闭游标

描述:

    程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor 后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险。

 

示例代码:

Cursor cursor = getContentResolver().query(uri ...);

if (cursor.moveToNext()) {

    ... ... 

}

 

修正示例代码:

Cursor cursor = null;

try {

    cursor = getContentResolver().query(uri ...);

    if (cursor != null && cursor.moveToNext()) {

        ... ... 

    }

} finally {

    if (cursor != null) {

        try { 

            cursor.close();

        } catch (Exception e) {

            //ignore this

        }

    }

 

(二 )  构造 Adapter 时,没有使用缓存的  convertView

描述:

    以构造ListView 的 BaseAdapter 为例,在 BaseAdapter 中提高了方法:

public View getView(int position, View convertView, ViewGroup parent)

来向ListView 提供每一个 item 所需要的 view 对象。初始时 ListView 会从 BaseAdapter 中根据当前的屏幕布局实例化一定数量的 view 对象,同时 ListView 会将这些 view 对象缓存起来。当向上滚动 ListView 时,原先位于最上面的 list item 的 view 对象会被回收,然后被用来构造新出现的最下面的 list item 。这个构造过程就是由 getView() 方法完成的, getView() 的第二个形参  View convertView 就是被缓存起来的 list item 的 view 对象 ( 初始化时缓存中没有 view 对象则 convertView 是 null) 。

    由此可以看出,如果我们不去使用convertView ,而是每次都在 getView() 中重新实例化一个 View 对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。 ListView 回收 list item 的 view 对象的过程可以查看 :

android.widget.AbsListView.java --> void addScrapView(View scrap) 方法。

 

示例代码:

public View getView(int position, View convertView, ViewGroup parent) {

    View view = new Xxx(...);

    ... ...

    return view;

}

 

修正示例代码:

public View getView(int position, View convertView, ViewGroup parent) {

    View view = null;

    if (convertView != null) {

        view = convertView;

        populate(view, getItem(position));

        ...

    } else {

        view = new Xxx(...);

        ...

    }

    return view;

 

(三 ) Bitmap 对象不在使用时调用 recycle() 释放内存

描述:

    有时我们会手工的操作Bitmap 对象,如果一个 Bitmap 对象比较占内存,当它不在被使用的时候,可以调用 Bitmap.recycle() 方法回收此对象的像素所占用的内存,但这不是必须的,视情况而定。可以看一下代码中的注释:

    /**

     * Free up the memory associated with this bitmap's pixels, and mark the

     * bitmap as "dead", meaning it will throw an exception if getPixels() or

     * setPixels() is called, and will draw nothing. This operation cannot be

     * reversed, so it should only be called if you are sure there are no

     * further uses for the bitmap. This is an advanced call, and normally need

     * not be called, since the normal GC process will free up this memory when

     * there are no more references to this bitmap.

     */

(四 )  释放对象的引用

描述:

    这种情况描述起来比较麻烦,举两个例子进行说明。

示例A :

假设有如下操作

public class DemoActivity extends Activity {

    ... ...

    private Handler mHandler = ...

    private Object obj;

    public void operation() {

       obj = initObj();

       ...

       [Mark]

       mHandler.post(new Runnable() {

            public void run() {

               useObj(obj);

            }

       });

    }

}

    我们有一个成员变量 obj ,在 operation() 中我们希望能够将处理 obj 实例的操作 post 到某个线程的 MessageQueue 中。在以上的代码中,即便是 mHandler 所在的线程使用完了 obj 所引用的对象,但这个对象仍然不会被垃圾回收掉,因为 DemoActivity.obj 还保有这个对象的引用。所以如果在 DemoActivity 中不再使用这个对象了,可以在 [Mark] 的位置释放对象的引用,而代码可以修改为:

... ...

public void operation() {

    obj = initObj();

    ...

    final Object o = obj;

    obj = null;

    mHandler.post(new Runnable() {

        public void run() {

            useObj(o);

        }

    }

}

... ...

 

示例B:

    假设我们希望在锁屏界面(LockScreen) 中,监听系统中的电话服务以获取一些信息 ( 如信号强度等 ) ,则可以在 LockScreen 中定义一个 PhoneStateListener 的对象,同时将它注册到 TelephonyManager 服务中。对于 LockScreen 对象,当需要显示锁屏界面的时候就会创建一个 LockScreen 对象,而当锁屏界面消失的时候 LockScreen 对象就会被释放掉。

    但是如果在释放LockScreen 对象的时候忘记取消我们之前注册的 PhoneStateListener 对象,则会导致 LockScreen 无法被垃圾回收。如果不断的使锁屏界面显示和消失,则最终会由于大量的 LockScreen 对象没有办法被回收而引起 OutOfMemory, 使得 system_process 进程挂掉。

    总之当一个生命周期较短的对象A ,被一个生命周期较长的对象 B 保有其引用的情况下,在 A 的生命周期结束时,要在 B 中清除掉对 A 的引用。

(五 )  其他

    Android应用程序中最典型的需要注意释放资源的情况是在 Activity 的生命周期中,在 onPause() 、 onStop() 、 onDestroy() 方法中需要适当的释放资源的情况。由于此情况很基础,在此不详细说明,具体可以查看官方文档对 Activity 生命周期的介绍,以明确何时应该释放哪些资源

_Android_内存泄漏调试.pdf,以下有下载:


    
最新技术文章:
▪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按钮单击事件的四种常用写法总结
编程语言 iis7站长之家
▪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