android如何显示多个View

setcontentview(view1);setcontentview(view2);只能显示后面那个view,如何能显示两个啊,求助... setcontentview(view1);setcontentview(view2);只能显示后面那个view,如何能显示两个啊,求助 展开
 我来答
osh3lzfp9
2011-04-07 · TA获得超过1129个赞
知道小有建树答主
回答量:1332
采纳率:0%
帮助的人:808万
展开全部
关系型数据库SQLite3,它是一个支持SQL轻量级的嵌入式数据库,在嵌入式操作上有很广泛的,WM采用的也是SQLite3

关于过于、原理方面的东西在这篇文章里不会提到,但是如果你想能够快速的学会操作SQLite3,那这就是你要找的文章!

首先,我们看一下api,所有数据库相关的接口、类都在.database和android.database.sqlite两个包下,虽然只有两个包,但是如果你英文不好或是太懒的话也要迷茫一段时间,其实,我们真正用的到的没有几个!

1、SQLiteOpenHelper (android.database.sqlite.SQLiteOpenHelper)

这是一个抽象类,关于抽象类我们都知道,如果要使用它,一定是继承它!

这个类的方法很少,有一个构造方法

SQLiteOpenHelper(android.content.Context context, java.lang.String name,android.database.sqlite.SQLiteDatabase.CursorFactory factory, int version);

参数不做过多的解释,CursorFactory一般直接传null就可以

public void onCreate(SQLiteDatabase db)

此方法在创建数据库是被调用,所以,应该把创建表的操作放到这个方法里面,一会儿在后面我们会再详细的说如何创建表

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

从方法名上我们就能知道这个方法是执行更新的,没错,当version改变是系统会调用这个方法,所以在这个方法里应该执行删除现有表,然后手动调用onCreate的操作

SQLiteDatabase getReadableDatabase()

可读的SQLiteDatabase对象

SQLiteDatabase getWritableDatabase()

获取可写的SQLiteDatabase对象

2、SQLiteDatabase(android.database.sqlite.SQLiteDatabase)

关于操作数据库的工作(增、删、查、改)都在这个类里

execSQL(sql)

执行SQL语句,用这个方法+SQL语句可以非常方便的执行增、删、查、改

除此之外,Android还提供了功过方法实现增、删、查、改

long insert(TABLE_NAME, null, contentValues)添加记录

int delete(TABLE_NAME, where, whereValue)删除记录

int update(TABLE_NAME, contentValues, where, whereValue) 更新记录

Cursor query(TABLE_NAME, null, null, null, null, null, null) 查询记录

除此之外,还有很多方法,如:beginTransaction()开始事务、endTransaction()结束事务...有兴趣的可以自己看api,这里就不多赘述了

3、Cursor(android.database.Cursor)

游标(接口),这个很熟悉了吧,Cursor里的方法非常多,常用的有:

boolean moveToPosition(position)将指针移动到某记录

getColumnIndex(Contacts.People.NAME)按列名获取id

int getCount()获取记录总数

boolean requery()重新查询

boolean isAfterLast()指针是否在末尾

boolean isBeforeFirst()时候是开始位置

boolean isFirst()是否是第一条记录

boolean isLast()是否是最后一条记录

boolean moveToFirst()、 boolean moveToLast()、 boolean moveToNext()同moveToPosition(position)

4、SimpleCursorAdapter(android.widget.SimpleCursorAdapter)

也许你会奇怪了,之前我还说过关于数据库的操作都在database和database.sqlite包下,为什么把一个Adapter放到这里,如果你用过Android的SQLite3,你一定会知道

,这是因为我们对数据库的操作会经常跟列表联系起来

经常有朋友会在这出错,但其实也很简单

SimpleCursorAdapter adapter = new SimpleCursorAdapter(

this,

R.layout.list,

myCursor,

new String[] ,

new int[]);

my.setAdapter(adapter);

一共5个参数,具体如下:

参数1:Content

参数2:布局

参数3:Cursor游标对象

参数4:显示的字段,传入String[]

参数5:显示字段使用的组件,传入int[],该数组中是TextView组件的id

到这里,关于数据库的操作就结束了,但是到目前为止我只做了翻译的工作,有些同学可能还是没有掌握,放心,下面我们一起顺着正常开发的思路理清一下头绪!

前面的只是帮没做过的朋友做下普及,下面才是你真正需要的!

一、写一个类继承SQLiteOpenHelpe

public class DatabaseHelper extends SQLiteOpenHelper

构造方法:

DatabaseHelper(Context context) {

super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

在onCreate方法里写建表的操作

public void onCreate(SQLiteDatabase db) {

String sql = "CREATE TABLE tb_test (_id INTEGER DEFAULT '1' NOT NULL PRIMARY KEY AUTOINCREMENT,class_jb TEXT NOT NULL,class_ysbj TEXT NOT NULL,title TEXT NOT NULL,content_ysbj TEXT NOT NULL)";

db.execSQL(sql);//需要异常捕获

}

在onUpgrade方法里删除现有表,然后手动调用onCtreate创建表

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

String sql = "drop table "+tbname;

db.execSQL(sql);

onCreate(db);

}

对表增、删、查、改的方法,这里用的是SQLiteOpenHelper提供的方法,也可以用sql语句实现,都是一样的

关于获取可读/可写SQLiteDatabase,我不说大家也应该会想到,只有查找才会用到可读的SQLiteDatabase

/**

* 添加数据

*/

public long insert(String tname, int tage, String ttel){

SQLiteDatabase db= getWritableDatabase();//获取可写SQLiteDatabase对象

//ContentValues类似map,存入的是键值对

ContentValues contentValues = new ContentValues();

contentValues.put("tname", tname);

contentValues.put("tage", tage);

contentValues.put("ttel", ttel);

return db.insert(tbname, null, contentValues);

}

/**

* 删除记录

* @param _id

*/

public void delete(String _id){

SQLiteDatabase db= getWritableDatabase();

db.delete(tbname,

"_id=?",

new String[]);

}

/**

* 更新记录的,跟插入的很像

*/

public void update(String _id,String tname, int tage, String ttel){

SQLiteDatabase db= getWritableDatabase();

ContentValues contentValues = new ContentValues();

contentValues.put("tname", tname);

contentValues.put("tage", tage);

contentValues.put("ttel", ttel);

db.update(tbname, contentValues,

"_id=?",

new String[]);

}

/**

* 查询所有数据

* @return Cursor

*/

public Cursor select(){

SQLiteDatabase db = getReadableDatabase();

return db.query(

tbname,

new String[],

null,

null, null, null, "_id desc");

}

关于db.query方法的参数,有很多,为了防止大家弄乱,我简单说一下

参数1:表名

参数2:返回数据包含的列信息,String数组里放的都是列名

参数3:相当于sql里的where,sql里where后写的内容放到这就行了,例如:tage>?

参数4:如果你在参数3里写了?(知道我为什么写tage>?了吧),那个这里就是代替?的值 接上例:new String[]

参数5:分组,不解释了,不想分组就传null

参数6:having,想不起来的看看SQL

参数7:orderBy排序

到这里,你已经完成了最多的第一步!我们来看看都用到了那些类:

SQLiteOpenHelper我们继承使用的

SQLiteDatabase增删查改都离不开它,即使你直接用sql语句,也要用到execSQL(sql)

二、这里无非是对DatabaseHelper类定义方法的调用,没什么可说的,不过我还是对查询再唠叨几句吧

Android查询出来的结果一Cursor形式返回

cursor = sqLiteHelper.select();//是不是很简单?

查询出来的cursor一般会显示在listView中,这就要用到刚才提到的SimpleCursorAdapter

SimpleCursorAdapter adapter = new SimpleCursorAdapter(

this,

R.layout.list_row,

cursor,

new String[],

new int[]

);

里面带有实例。自己好好学习吧!
作文小编
推荐于2016-02-08 · TA获得超过33.9万个赞
知道大有可为答主
回答量:2.5万
采纳率:0%
帮助的人:4673万
展开全部
setcontentview(view1);
view1.addview(view2);
1.对于控制事件今天我们只处理按键事件onKeyDown,

  2.刷新view的方法这里主要有

  invalidate(int l,int t,int r,int b) 刷新局部,四个参数分别为左、上、右、下

  整个view刷新 invalidate()

  刷新一个矩形区域invalidate(Rect dirty)

  刷新一个特性DrawableinvalidateDrawable(Drawable drawable)

  执行invalidate类的方法将会设置view为无效,最终导致onDraw方法被重新调用。

  今天的view比较简单,大家如果在线程中刷新,除了使用handler方式外,可以在Thread中直接使用postInvalidate方法来实现。

  3. 绘制View主要是onDraw()中通过形参canvas来处理,相关的绘制主要有drawRect、drawLine、drawPath等等。

  view方法内部还重写了很多接口,其回调方法可以帮助我们判断出view的位置和大小,比如onMeasure(int, int) Called to determine the size requirements for this view and all of its children。 、onLayout(boolean, int, int, int, int) Called when this view should assign a size and position to all of its children 和onSizeChanged(int, int, int, int) Called when the size of this view has changed。 具体的作用,大家可以用Logcat获取当view变化时每个形参的变动。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
s_potat0
2011-04-07
知道答主
回答量:12
采纳率:0%
帮助的人:8.9万
展开全部
其实在android里面一个你说的view相当于一个窗口
android不是电脑它只能同时显示一个窗口
所以你的想法是不可能的。。。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
nehcam
2011-04-06 · TA获得超过221个赞
知道答主
回答量:139
采纳率:0%
帮助的人:132万
展开全部
setcontentview(view1);
view1.addview(view2);
追问
不行啊,我说的是view1和view2显示在屏幕的不同地方,如果addview,应该是view2显示在view1上面吧,不过addview也不行
追答
那你可以先用一个RelativeLayout作为contentview,然后将view1,view2分别add进去,再通过layout params调整位置
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
1219866500
2015-06-16 · TA获得超过1936个赞
知道小有建树答主
回答量:467
采纳率:50%
帮助的人:330万
展开全部
如果很平常的两个listview组件竖直放在linearLayout布局中,结果是:
两个listview 很独立,中间似乎有个分割线,完全吧他们分离了,各自独立滚动,如果上面的listview把整个屏幕占据了,那么下面的listview永远滚不上来了,看不到了。

网上关于这个话题大约有两种方法解决:
(1)有多少个listview就用多少个listview组件,然后放在一个LinearLayout布局里面,linearLayout布局在放入Scrollview中。
这样做,必须先计算出每个listview被对应的adapter适配之后的实际高度,然后设置listview为这个高度。再放入scrollview中ok了。

(2)不管有多少个listview,都放在一个listview,用一个adapter适配,在listview组件对应的数据存储结构list中,设置flag标志位,在adapter中再对不同的flag做不同的适配。

一开始,项目中使用的第一种方法,随着项目的进行,发现第一种方法会在很多种情况下不适应,最严重的问题,就是第一种方法非常耗时,已经到了一种无可忍受的地步了。
一个很常见的例子,城市列表,有两个list:热门城市、全部城市

假如用第一种方法,先计算两个listview在对应的adapter适配后的高度:
[java] view plaincopy
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}

ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
[java] view plaincopy
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}

ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
其实从这段代码中,和上面这个需求,问题已经可以看出来了。

adapter有一个方法getView,这个方法是如果这个listview的某行将要在屏幕上显示了,系统就会自动调用getview得到这个布局,然后显示。
也就是每次被调用的次数,只是屏幕上能显示的条数,最多也就是10条左右。
而一次计算高度就要对每一条调用getview,for循环里面:
[java] view plaincopy
View listItem = listAdapter.getView(i, null, listView);
[java] view plaincopy
View listItem = listAdapter.getView(i, null, listView);
是非常耗时的,尤其对于全部城市,几百条,3~4秒肯定是要的。所以面对这个需求,第一种方法是不可行。

除了耗时,第一种方法,维护性也不好。就比如,一个页面中,listview的数据是不定的,是动态计算得到的。用第一种方法分散到多个listview,对于一些事件监听,不好操作。

下面讲解下第二种方法的具体实现
拿上面城市列表具体
分两块:
1、数据dataList
2、adapter
1、datalist填充:
主要以一个flag标记,对于城市列表共有两种布局:
一个是头信息

一个是具体的城市

代码:
[java] view plaincopy
cityList.clear();
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("city", new City(0, "热门城市", '#'));
cityList.add(map1);

List<City> cities = getHotCity();

for (City city : cities) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("is_selected", false);
map.put("city", city);
cityList.add(map);
}

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("city", new City(0, "全部城市", '$'));
cityList.add(map2);

index++;
cities = getAllCity();

for (City city : cities) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("is_selected", false);
map.put("city", city);
cityList.add(map);
}
[java] view plaincopy
cityList.clear();
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("city", new City(0, "热门城市", '#'));
cityList.add(map1);

List<City> cities = getHotCity();

for (City city : cities) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("is_selected", false);
map.put("city", city);
cityList.add(map);
}

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("city", new City(0, "全部城市", '$'));
cityList.add(map2);

index++;
cities = getAllCity();

for (City city : cities) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("is_selected", false);
map.put("city", city);
cityList.add(map);
}

哦~这个好像没用到flag标记,直接判断city的name了~~~
2、adapter适配:
[java] view plaincopy
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
City city = (City) listData.get(position).get("city");
String nameString = city.getName();
if (nameString.compareTo("热门城市") == 0) {
convertView = mInflater.inflate(headResource, null);
((TextView) convertView.findViewById(R.id.label)).setText("热门城市");
return convertView;
}
if (nameString.compareTo("全部城市") == 0) {
convertView = mInflater.inflate(headResource, null);
((TextView) convertView.findViewById(R.id.label)).setText("全部城市");
return convertView;
}

convertView = mInflater.inflate(listResource, null);
((TextView) convertView.findViewById(R.id.label)).setText(nameString);
ImageView isSelectedImageView = (ImageView) convertView.findViewById(R.id.is_selected);

// boolean isSelected = (Boolean) listData.get(position).get("is_selected");

int whichIsSelected = (Integer) listData.get(getCount() - 1).get("which_is_selected");

if (city.getId() == whichIsSelected)
isSelectedImageView.setBackgroundResource(R.drawable.is_selected_yes);
else
isSelectedImageView.setBackgroundResource(R.drawable.is_selected_no);

return convertView;
}
[java] view plaincopy
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
City city = (City) listData.get(position).get("city");
String nameString = city.getName();
if (nameString.compareTo("热门城市") == 0) {
convertView = mInflater.inflate(headResource, null);
((TextView) convertView.findViewById(R.id.label)).setText("热门城市");
return convertView;
}
if (nameString.compareTo("全部城市") == 0) {
convertView = mInflater.inflate(headResource, null);
((TextView) convertView.findViewById(R.id.label)).setText("全部城市");
return convertView;
}

convertView = mInflater.inflate(listResource, null);
((TextView) convertView.findViewById(R.id.label)).setText(nameString);
ImageView isSelectedImageView = (ImageView) convertView.findViewById(R.id.is_selected);

// boolean isSelected = (Boolean) listData.get(position).get("is_selected");

int whichIsSelected = (Integer) listData.get(getCount() - 1).get("which_is_selected");

if (city.getId() == whichIsSelected)
isSelectedImageView.setBackgroundResource(R.drawable.is_selected_yes);
else
isSelectedImageView.setBackgroundResource(R.drawable.is_selected_no);

return convertView;
}

对于各行的点击操作也可以根据flag统一处理。维护起来非常方便。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式