在 ListActivity 的 CustomView 中以编程方式更改 LayoutParams 对某些项目没有影响
我在列表视图中呈现项目时出现奇怪的行为。我将尽力解释:
我创建了一个 CustomView 用作 ListView 中的项目。 此 CustomView 有一个 Framelayout 作为根视图和 2 个子视图:
1) 一个 LinearLayout,其中有一堆 TextView 作为子视图
2) 顶部(最后一个添加到框架布局)有一个带背景的 View 当我按下它时改变颜色的选择器。 (只是为了给用户一个视觉提示,表明我选择了该项目...
现在的问题...由于文本视图可以更改其高度,因为它们是多行的,所以我需要相应地更改顶视图的高度。 .. 由于顶视图和 LinearLayout 在 Framelayout 中位于同一级别,因此我无法在 xml 文件中执行此操作。
所以我扩展了一个 FrameLayout,膨胀了自定义视图的 xml 文件并覆盖了 onLayout(...)。这样做我可以获得 LinearLayout 的高度并将其传递到顶视图:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b){
super.onLayout(changed, l, t, r, b);
LinearLayout ll = (LinearLayout) findViewById(R.id.linear_layout_items);
int height = ll.getMeasuredHeight();
//Setting the height in the View...
View view = findViewById(R.id.click_view);
view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}
现在,除了某些情况之外,这可以完美地工作......
如果屏幕能够渲染前 4 个项目,并且我滚动到第 5 个项目,则顶视图的高度(带有 id R.id.click_view)被设置为 0,尽管它设置正确......并且如果我开始滚动,这开始随机发生......
我已经在运行 android 3.1 的平板电脑上进行了测试运行 ICS 的模拟器,它工作得很好...它只在运行版本 <=2.x 的设备中失败...
有关如何修复此行为的任何提示吗?
预先感谢您的任何帮助或提示。
这是完整的代码: 活动项目
public class DemoCursorActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init()
{
MatrixCursor cursor = new MatrixCursor(new String[]{ "_id", "txt1", "txt2", "txt3","txt4" });
cursor.addRow(new Object[]{ 1, "1111111111","1111111111","1111111111","1111111111" });
cursor.addRow(new Object[]{ 2, "2222222222","2222222222","2222222222","2222222222" });
cursor.addRow(new Object[]{ 3, "3333333333","3333333333","3333333333","3333333333" });
cursor.addRow(new Object[]{ 4, "4444444444","4444444444","4444444444","4444444444" });
cursor.addRow(new Object[]{ 5, "5555555555","5555555555","5555555555","5555555555" });
cursor.addRow(new Object[]{ 6, "6666666666","6666666666","6666666666","6666666666" });
cursor.addRow(new Object[]{ 7, "7777777777","7777777777","7777777777","7777777777" });
cursor.addRow(new Object[]{ 8, "8888888888","8888888888","8888888888","8888888888" });
ItemsCursorAdapter cursorAdapter = new ItemsCursorAdapter (this, cursor);
setListAdapter(cursorAdapter);
}
class ItemsCursorAdapter extends CursorAdapter
{
private final LayoutInflater mInflater;
public ItemsCursorAdapter(Context context, Cursor cursor) {
super(context, cursor);
mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View v, Context context, Cursor cursor)
{
Resources res = context.getResources();
TextView tv1 = (TextView) v.findViewById(R.id.text1);
TextView tv2 = (TextView) v.findViewById(R.id.text2);
TextView tv3 = (TextView) v.findViewById(R.id.text3);
TextView tv4 = (TextView) v.findViewById(R.id.text4);
tv1.setText(cursor.getString(1));
tv2.setText(cursor.getString(2));
tv3.setText(cursor.getString(3));
tv4.setText(cursor.getString(4));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
View v = new ListItemWidget(context);
bindView(v, context, cursor);
return v;
}
}
布局文件:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF" >
<LinearLayout
android:id="@+id/linear_layout_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
</LinearLayout>
<View
android:id="@+id/click_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/group_item_backgroud_selector" />
</FrameLayout>
和我的自定义视图:
public class ListItemWidget extends FrameLayout
{
public ListItemWidget(Context context) {
super(context);
inflate(context, R.layout.list_item, this);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
LinearLayout ll = (LinearLayout) findViewById(R.id.LinearLayout01);
int height = ll.getMeasuredHeight();
View view = findViewById(R.id.click_view);
view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}
}
I’m having a strange behavior rendering items in a Listview. I’ll try to explain as best as I can:
I've created a CustomView to be used as items in a ListView.
This CustomView has a Framelayout as the root view and 2 child's:
1) A LinearLayout with a bunch of TextView's as childs
2) and on the top (the last to be added to the framelayout) a View with a background
selector that change color when I press it. (Just to give a visual hint to the user that I had selected the item...
Now the problem... since the textviews can change theirs heights, because they are multiline, I need to change the height of the top view accordingly...
And since the top view and the linearLayout are on the same level in the Framelayout, I cannot do this in xml file.
So I had extended an FrameLayout, inflated the xml file of the custom view and override the onLayout(...). Doing this I can get the height of the LinearLayout and pass it to the top view:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b){
super.onLayout(changed, l, t, r, b);
LinearLayout ll = (LinearLayout) findViewById(R.id.linear_layout_items);
int height = ll.getMeasuredHeight();
//Setting the height in the View...
View view = findViewById(R.id.click_view);
view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}
Now this works flawlessly, except for some cases...
If the screen is capable of rendering the first 4 items and I scroll to the 5th item, the height of the top view (with the id R.id.click_view) in the is set to 0, although it was set correctly... And if I start to scroll around, this starts to happen randomly....
I've tested this in a tablet running android 3.1 and in an emulator running ICS and it works perfectly... It only fails in devices running versions <=2.x…
Any tip on how to fix this behaviour?
Thanks in advance for any help or tips.
This is the complete code:
Activity
public class DemoCursorActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init()
{
MatrixCursor cursor = new MatrixCursor(new String[]{ "_id", "txt1", "txt2", "txt3","txt4" });
cursor.addRow(new Object[]{ 1, "1111111111","1111111111","1111111111","1111111111" });
cursor.addRow(new Object[]{ 2, "2222222222","2222222222","2222222222","2222222222" });
cursor.addRow(new Object[]{ 3, "3333333333","3333333333","3333333333","3333333333" });
cursor.addRow(new Object[]{ 4, "4444444444","4444444444","4444444444","4444444444" });
cursor.addRow(new Object[]{ 5, "5555555555","5555555555","5555555555","5555555555" });
cursor.addRow(new Object[]{ 6, "6666666666","6666666666","6666666666","6666666666" });
cursor.addRow(new Object[]{ 7, "7777777777","7777777777","7777777777","7777777777" });
cursor.addRow(new Object[]{ 8, "8888888888","8888888888","8888888888","8888888888" });
ItemsCursorAdapter cursorAdapter = new ItemsCursorAdapter (this, cursor);
setListAdapter(cursorAdapter);
}
class ItemsCursorAdapter extends CursorAdapter
{
private final LayoutInflater mInflater;
public ItemsCursorAdapter(Context context, Cursor cursor) {
super(context, cursor);
mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View v, Context context, Cursor cursor)
{
Resources res = context.getResources();
TextView tv1 = (TextView) v.findViewById(R.id.text1);
TextView tv2 = (TextView) v.findViewById(R.id.text2);
TextView tv3 = (TextView) v.findViewById(R.id.text3);
TextView tv4 = (TextView) v.findViewById(R.id.text4);
tv1.setText(cursor.getString(1));
tv2.setText(cursor.getString(2));
tv3.setText(cursor.getString(3));
tv4.setText(cursor.getString(4));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
View v = new ListItemWidget(context);
bindView(v, context, cursor);
return v;
}
}
The item layout file:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF" >
<LinearLayout
android:id="@+id/linear_layout_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/text4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textColor="#000"
android:textSize="20sp" />
</LinearLayout>
<View
android:id="@+id/click_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/group_item_backgroud_selector" />
</FrameLayout>
and my custom view:
public class ListItemWidget extends FrameLayout
{
public ListItemWidget(Context context) {
super(context);
inflate(context, R.layout.list_item, this);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
LinearLayout ll = (LinearLayout) findViewById(R.id.LinearLayout01);
int height = ll.getMeasuredHeight();
View view = findViewById(R.id.click_view);
view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论