java - 将视图动态添加到自定义 ListView 项目布局不起作用
问题描述
我希望为每个 ListView 项目添加一个定制的布局。我在 ListView 项目布局的 xml 布局文件中有一个空的线性布局。它具有水平方向。
我希望将三个 FrameLayout 动态添加到上述 LinearLayout 并为每个 FrameLayout 设置自定义权重。
我找到了解决方案的一部分,如下面的代码所示。必须更新 ListView 时会出现问题。ListView 最初是隐藏的。当按下某个按钮时,ListView 得到更新(散列图被清除,然后用新的数据集填充)并且它的可见性设置从 GONE 到 VISIBLE。接下来是遍历所有项目并以编程方式添加设计视图。
如果我在更新 ListView 项目后立即调用该方法add_designed_views(null);
,则应用程序会遍历项目,创建所有新视图并将它们添加到正确的项目中。但是,它们没有被添加。我知道这一点是因为检查该项目是否已添加,如果我连续多次调用此方法,它每次都会执行相同的操作,就好像它根本没有添加任何东西一样。
我尝试的下一件事是通过调用虚拟按钮的方法add_designed_views
来推迟动态添加视图。onClick
当我看到列表已加载(没有自定义视图)时,我按下虚拟按钮并出现自定义视图。但是每 6 个都不见了。如果我再次按下它,就会出现丢失的那些。这让我更加困惑。
很明显,更改ListView的可见性后不能立即添加视图。可能是因为系统需要一些时间来填充 ListView,或者它执行了一些后台任务,但我找不到任何侦听器或某些函数告诉我它已完成加载,以便我可以添加我的视图。
自定义 ListView 项目布局(xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="110dp"
android:background="@drawable/textview_border_dark_line"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="21"
android:minHeight="40dp">
<TextView
android:id="@+id/text1"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#000000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="15dp"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="70"
android:minHeight="90dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/path_model"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:orientation="horizontal"
android:onClick="onClick_listItem"
>
<!-- Path Model. -->
<!-- This is where I add view dynamically. -->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="40"
android:orientation="vertical">
<TextView
android:id="@+id/text2"
android:textSize="12dp"
android:textColor="#454545"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="50"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10">
<ImageView
android:id="@+id/ic_time"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/clock"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/text4_1"
android:textSize="14dp"
android:textColor="#454545"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/ic_time" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10">
<ImageView
android:id="@+id/ic_changes"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/change"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/text4_2"
android:textSize="14dp"
android:textColor="#454545"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/ic_changes"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10">
<ImageView
android:id="@+id/ic_cost"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/coins"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/text4_3"
android:textSize="14dp"
android:textColor="#454545"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/ic_cost"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10">
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="21"
android:minHeight="38dp">
<TextView
android:id="@+id/text3"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#000000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="15dp"
/>
</RelativeLayout>
</LinearLayout>
add_design_views 方法(Java):
public void add_designed_views(View view)
{
for(int i=0; i<hashmap_search_results_list.size(); i++)
{
/* Check if it is already added. We have to check,
because we run it twice in consecutive order. */
LinearLayout listView_item = (LinearLayout)getViewByPosition(i, listView_search_results);
View middle_ground = ((ViewGroup) listView_item).getChildAt(1);
LinearLayout path_model = (LinearLayout) ((ViewGroup) middle_ground).getChildAt(0);
LinearLayout already_added_ll_path = (LinearLayout)((ViewGroup)path_model).getChildAt(0);
if(already_added_ll_path != null)
{
Log.d(TAG, "Already has linear layout: " + hashmap_search_results_list.get(i).get("latest_departure_time"));
continue;
}
Log.d(TAG, "Doing: " + hashmap_search_results_list.get(i).get("latest_departure_time"));
Search_Result_Item result_item = (Search_Result_Item)search_results_list.get(i);
/* How to access each view at each item position in list view. */
//LinearLayout listView_item = (LinearLayout) getViewByPosition(i, listView_search_results);
//View middle_ground = ((ViewGroup) listView_item).getChildAt(1);
//LinearLayout path_model = (LinearLayout) ((ViewGroup) middle_ground).getChildAt(0);
/* Setting the proportions of lines regarding walking time and riding time. */
HrMin hrmin_walking_to_entrance_time = result_item.walking_to_entrance_time();
HrMin hrmin_riding_time = result_item.travel_time();
HrMin hrmin_walking_from_exit_time = result_item.walking_from_exit_time();
int int_walking_to_entrance_time = hrmin_get_minutes(hrmin_walking_to_entrance_time);
int int_riding_time = hrmin_get_minutes(hrmin_riding_time);
int int_walking_from_exit_time = hrmin_get_minutes(hrmin_walking_from_exit_time);
int total = int_walking_to_entrance_time +
int_riding_time +
int_walking_from_exit_time;
float weight_walking_to_entrance = (float)int_walking_to_entrance_time/total;
float weight_bus_ride = (float)int_riding_time/total;
float weight_walking_from_exit = (float)int_walking_from_exit_time/total;
/* How to add a new layout, view to existing layout. */
LinearLayout ll_path = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
/* Pedestrian image. */
ImageView pedestrian = new ImageView(this);
pedestrian.setBackground(getResources().getDrawable(R.drawable.runner_rnd));
int dimensionInPixel = 16;
int dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams pedestrian_params = new FrameLayout.LayoutParams(
dimensionInDp,
dimensionInDp,
Gravity.CENTER_VERTICAL);
pedestrian.setLayoutParams(pedestrian_params);
/* Gray Line. */
FrameLayout frameLayout_pedestrian_container = new FrameLayout(this);
LinearLayout.LayoutParams frame_layout_params = new LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.MATCH_PARENT,
weight_walking_to_entrance);
View gray_line = new View(this);
gray_line.setBackground(getResources().getDrawable(R.drawable.horizontal_gray_line));
dimensionInPixel = 4;
dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams gray_line_params = new FrameLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dimensionInDp,
Gravity.CENTER_VERTICAL);
gray_line.setLayoutParams(gray_line_params);
frameLayout_pedestrian_container.addView(gray_line);
frameLayout_pedestrian_container.addView(pedestrian);
frameLayout_pedestrian_container.setLayoutParams(frame_layout_params);
ll_path.addView(frameLayout_pedestrian_container);
/* Bus image. */
FrameLayout frameLayout_bus_container = new FrameLayout(this);
LinearLayout.LayoutParams frame_layout_bus_params = new LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.MATCH_PARENT,
weight_bus_ride);
ImageView bus = new ImageView(this);
bus.setBackground(getResources().getDrawable(R.drawable.bus_rnd));
dimensionInPixel = 17;
dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams bus_params = new FrameLayout.LayoutParams(
dimensionInDp,
dimensionInDp,
Gravity.CENTER_VERTICAL);
bus.setLayoutParams(bus_params);
/* Green line. */
View green_line = new View(this);
green_line.setBackground(getResources().getDrawable(R.drawable.horizontal_green_line));
dimensionInPixel = 4;
dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams green_line_params = new FrameLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dimensionInDp,
Gravity.CENTER_VERTICAL);
green_line.setLayoutParams(green_line_params);
frameLayout_bus_container.addView(green_line);
frameLayout_bus_container.addView(bus);
frameLayout_bus_container.setLayoutParams(frame_layout_bus_params);
ll_path.addView(frameLayout_bus_container);
/* Walking from exit path. */
ImageView pedestrian2 = new ImageView(this);
pedestrian2.setBackground(getResources().getDrawable(R.drawable.runner_rnd));
dimensionInPixel = 16;
dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams pedestrian_params2 = new FrameLayout.LayoutParams(
dimensionInDp,
dimensionInDp,
Gravity.CENTER_VERTICAL);
pedestrian2.setLayoutParams(pedestrian_params2);
/* Gray Line. */
FrameLayout frameLayout_pedestrian_container2 = new FrameLayout(this);
LinearLayout.LayoutParams frame_layout_params2 = new LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.MATCH_PARENT,
weight_walking_from_exit);
View gray_line2 = new View(this);
gray_line2.setBackground(getResources().getDrawable(R.drawable.horizontal_gray_line));
dimensionInPixel = 4;
dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());
FrameLayout.LayoutParams gray_line_params2 = new FrameLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dimensionInDp,
Gravity.CENTER_VERTICAL);
gray_line2.setLayoutParams(gray_line_params2);
frameLayout_pedestrian_container2.addView(gray_line2);
frameLayout_pedestrian_container2.addView(pedestrian2);
frameLayout_pedestrian_container2.setLayoutParams(frame_layout_params2);
ll_path.addView(frameLayout_pedestrian_container2);
ll_path.setLayoutParams(params);
ll_path.setOrientation(LinearLayout.HORIZONTAL);
path_model.addView(ll_path);
}
}
我更新 ListView 并显示它的部分:
search_results.setVisibility(View.VISIBLE);
ListView 是两种布局的子视图:
<LinearLayout
android:id="@+id/search_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:visibility="gone"
android:paddingTop="140dp"
android:orientation="vertical"
android:onClick="onClick_nothing">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_options_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="@+id/mapView"
app:layout_constraintTop_toTopOf="@+id/mapView"
android:background="@android:color/white"
android:orientation="vertical"
>
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarThumbVertical="@android:color/darker_gray"
/>
</RelativeLayout>
</LinearLayout>
解决方案
有帮助的一件事是Handler.postDelayed()
:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
add_designed_views (null);
}
}, 300);
此函数将方法调用延迟 300 毫秒。以编程方式添加的布局是可见的。但是,仍然每 6 次丢失。在我触摸任何项目后,它们也会出现。
推荐阅读
- python - 如何通过 Python 使用 Selenium 单击此按钮
- python - argparse:需要一个标志或 2+ 个位置参数
- html - 如何将内联块包装文本(换行后)推到右边?
- regex - 尝试从文本字段中提取数字
- c# - C# 弱引用在对象 GC 后仍然有效?
- c++ - Eclipse“最终启动序列中的错误:命令'-file-exec-and-symbols myprog.exe'超时
- nativescript - nativescript-image-zoom 不能以角度工作
- c - 我如何知道要使用哪个 I/O 分配函数(request_region VS. request_mem_region)?
- reporting-services - 为什么我不断收到“textrun 中使用的值表达式返回的数据类型无效。” 错误?
- python - 如何让玩家知道他们赢得了刽子手?