我在 ViewPager 中有一个 fragment ,并尝试根据屏幕的大小动态更改 ListView 的高度。
这是我的 fragment 的 xml 代码:
fragment .xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<RelativeLayout
android:id="@+id/rlDiscoveredDevice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/tvSuggestBTOn">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvDiscoveredDevices"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:text="@string/text_list_discovered_devices"
/>
<ProgressBar
android:id="@+id/pbDiscoveredDevices"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/tvDiscoveredDevices"
android:layout_marginStart="16dp"
/>
<ListView
android:id="@+id/lstDiscoveredBTDevices"
android:layout_height="250dp"
android:layout_width="wrap_content"
android:divider="@android:color/transparent"
android:dividerHeight="@dimen/list_view_divider_height"
android:choiceMode="singleChoice"
android:listSelector="@color/list_item_selected"
android:layout_below="@+id/tvDiscoveredDevices"
android:layout_marginTop="@dimen/list_view_margin_top"
/>
</RelativeLayout>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pairBT"
android:background="@drawable/ic_action_down"
android:layout_marginStart="134dp"
android:layout_below="@+id/rlDiscoveredDevice"
android:layout_alignParentStart="true"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/unpairBT"
android:background="@drawable/ic_action_up"
android:layout_below="@+id/rlDiscoveredDevice"
android:layout_toEndOf="@+id/pairBT"
android:layout_marginStart="73dp"
/>
<RelativeLayout
android:id="@+id/rlPairedDevice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/pairBT">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvPairedDevices"
android:text="@string/text_list_paired_devices"
android:layout_alignParentStart="true"
/>
<ListView
android:id="@+id/lstPairedBTDevices"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:divider="@android:color/transparent"
android:dividerHeight="@dimen/list_view_divider_height"
android:choiceMode="singleChoice"
android:listSelector="@color/list_item_selected"
android:layout_below="@+id/tvPairedDevices"
android:layout_alignParentStart="true"
android:layout_marginTop="@dimen/list_view_margin_top"
/>
</RelativeLayout>
</RelativeLayout>
这是我用来动态更改高度的 java 代码:
DiscoveredDevice.java
public class DiscoveredDevice extends Fragment{
final String TAG = "DiscoverDevice Fragment";
private SharedPreferences appPrefs;
private BTActions btActions;
private ArrayList<BluetoothDevice> arrDiscoveredDevicesList;
private Set<BluetoothDevice> arrPairedDevicesList;
private ArrayAdapter<String> btDiscListArrayAdapter;
private ArrayAdapter<String> btPairedListArrayAdapter;
private String strDiscoveredListItemSelected = "";
private String strPairedListItemSelected = "";
private CommonFunctions cf;
private boolean blnIsFragmentLoaded = false;
// UI Objects
private TextView tvDiscoveredDevices;
private TextView tvPairedDevices;
private ListView lvDiscoveredList;
private ListView lvPairedDevicesList;
private ImageButton ibtnPair;
private ImageButton ibtnUnPair;
private ProgressBar pbDiscDevicesSpinner;
private TextView tvSuggestBTOn;
private ProgressBar pbLoading;
public DiscoveredDevice() {
btActions = new BTActions();
cf = new CommonFunctions();
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "Begin render of Discovered Device fragment...");
super.onCreate(savedInstanceState);
// Define variables
appPrefs = this.getActivity().getPreferences(Context.MODE_PRIVATE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_discovered_device, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Define the lists on DiscoveredDevice fragment
btDiscListArrayAdapter = new ArrayAdapter<>(getContext(), R.layout.simple_row, R.id.simple_row_Txt);
btPairedListArrayAdapter = new ArrayAdapter<>(getContext(), R.layout.simple_row, R.id.simple_row_Txt);
// Define UI Objects
defineUIObjects();
// Position UI objects
positionUIObjects();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
}
private void defineUIObjects() {
tvDiscoveredDevices = (TextView) getView().findViewById(R.id.tvDiscoveredDevices);
tvPairedDevices = (TextView) getView().findViewById(R.id.tvPairedDevices);
lvDiscoveredList = (ListView) getView().findViewById(R.id.lstDiscoveredBTDevices);
lvPairedDevicesList = (ListView) getView().findViewById(R.id.lstPairedBTDevices);
ibtnPair = (ImageButton) getView().findViewById(R.id.pairBT);
ibtnUnPair = (ImageButton) getView().findViewById(R.id.unpairBT);
tvSuggestBTOn = (TextView) getView().findViewById(R.id.tvSuggestBTOn);
pbDiscDevicesSpinner = (ProgressBar) getView().findViewById(R.id.pbDiscoveredDevices);
pbLoading = (ProgressBar) getView().findViewById(R.id.spin_kit_progress);
pbLoading.setIndeterminateDrawable(new DoubleBounce());
}
private void positionUIObjects() {
final ViewGroup vgDiscDevice = (ViewGroup) getView().findViewById(R.id.rlDiscoveredDevice);
final AtomicInteger aiLayoutHeight = new AtomicInteger();
Rect rect = new Rect();
// Get the window
Window win = getActivity().getWindow();
win.getDecorView().getWindowVisibleDisplayFrame(rect);
// Find height of AppBarLayout
AppBarLayout ablTabs = (AppBarLayout) getActivity().findViewById(R.id.ablTabs);
// Obtain the screen height & width
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
int intScreenHeight = metrics.heightPixels;
int intScreenWidth = metrics.widthPixels;
Log.i(TAG, "Actual Screen Height = " + intScreenHeight + " Width = " + intScreenWidth);
// Set the height for Discovered Devices list
RelativeLayout.LayoutParams rlParams = (RelativeLayout.LayoutParams) getView().findViewById(R.id.rlDiscoveredDevice).getLayoutParams();
// Get height of Discovered Devices relative layout
int intDiscoveredDevicesRLHeight = (int)(Math.round((intScreenHeight - rect.top - ablTabs.getMeasuredHeight()) * 0.45));
Log.i(TAG, "Setting the height of Discovered Devices Relative layout as '" + intDiscoveredDevicesRLHeight + "'");
rlParams.topMargin = ablTabs.getMeasuredHeight();
rlParams.leftMargin = 50; // I DID THIS JUST TO CHECK IF THE LEFT MARGIN GETS MOVED TO THE RIGHT. THIS IS WHERE I NEED A BETTER WAY TO PROPERLY ALIGN THE LIST
rlParams.height = intDiscoveredDevicesRLHeight;
lvDiscoveredList.setLayoutParams(rlParams);
}
我希望每个列表占据屏幕的 45%(不包括 AppBarLayout)。如果您看到下面的屏幕截图,当我设置新高度时,ListView 会失去对齐状态,并且它的一部分会被剪切到屏幕左侧。我已将左边距设置为 50 以使其可见。
[截图]
我在RelativeLayouts中放置了2个ListView,这样它们就可以作为一个整体单独控制。我在这里做错了什么吗?
最佳答案
我认为您只需使用 xml 即可实现此目的,无需动态调整大小!
在您的帖子中,您提到您希望每个 ListView 占据可用高度的 45%。因此,我假设 ImageView 的中心内容将占据高度的 10%(尽管如果它们具有固定高度,这种方法也适用,我也会在底部包含该答案。
您需要做的就是将顶级布局更改为 LinearLayout (具有垂直方向),将 ImageView 放入 LinearLayout (具有水平方向),更改 View 的一些高度并添加 layout_weight您将创建的两个RelativeLayouts 和内部LinearLayout 的属性。以下是 xml 的示例:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<RelativeLayout
android:id="@+id/rlDiscoveredDevice"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@+id/tvSuggestBTOn"
android:layout_weight="9">
<TextView
android:id="@+id/tvDiscoveredDevices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="@string/text_list_discovered_devices"
/>
<ProgressBar
android:id="@+id/pbDiscoveredDevices"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_toEndOf="@+id/tvDiscoveredDevices"
/>
<ListView
android:id="@+id/lstDiscoveredBTDevices"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tvDiscoveredDevices"
android:divider="@android:color/transparent"
android:dividerHeight="@dimen/list_view_divider_height"
android:choiceMode="singleChoice"
android:listSelector="@color/list_item_selected"
android:background="@drawable/abc_list_selector_disabled_holo_dark"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
android:layout_weight="2">
<ImageButton
android:id="@+id/pairBT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_action_down"
/>
<ImageButton
android:id="@+id/unpairBT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_action_up"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/rlPairedDevice"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvPairedDevices"
android:text="@string/text_list_paired_devices"
android:layout_alignParentStart="true"
/>
<ListView
android:id="@+id/lstPairedBTDevices"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="@dimen/list_view_divider_height"
android:choiceMode="singleChoice"
android:listSelector="@color/list_item_selected"
android:layout_below="@+id/tvPairedDevices"
android:layout_alignParentStart="true"
android:background="@drawable/abc_list_selector_disabled_holo_dark"
/>
</RelativeLayout>
</LinearLayout>
这里需要注意的重要一点是,RelativeLayouts 现在的权重均为 9,中心线性布局的权重为 2。因此,顶级线性布局中的空间将按该比例划分,RelativeLayouts 将分别获得 45%,LinearLayout 将获得 10%。
如果您希望中心的线性布局成为换行内容,而不是占据屏幕的 10%(我建议这样做),那么您可以继续为它分配一个 wrap_content 的高度,并从中删除 layout_weight 属性。然后,顶层 LinearLayout 将在为中心 LinearLayout 分配空间后获取剩余高度,并将其平均分配在两个相对布局之间。
PS:(注意,您可以使用我在此处发布的 xml。我在 ListView 上设置了背景,以便我可以轻松地在没有数据的情况下查看它们的大小,请确保删除这些)。
PPS:请注意,这种方法允许您删除顶级相对布局中的许多布局定位属性!这不仅可以提高代码的简洁性,还可以提高 UI 的性能 ( Relative Layouts are less performant than other view groups, especially when nested )。
关于java - 更改 ListView 的高度会破坏对齐方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38100899/