如何根据设备有效地更改布局
How to efficiently change layout based on device
为我的 activity 第一项使用相同的点击事件来调整布局的最有效方法是什么?我只看到 this and this 但他们没有完全解决问题。
当前phone代码
XML (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<ListView
android:id="@+id/my_listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Java
public class MainActivity extends Activity implements MyRecyclerViewAdapterGL.ItemClickListener, MyRecyclerViewAdapterLL.ItemClickListener {
MyRecyclerViewAdapterGL adapterGL;
MyRecyclerViewAdapterLL adapterLL;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// data to populate the RecyclerView with
String[] dataArray = {"Item A", "Item B", "Item C", "Item D" ,"Item E" ,"Item F"};
// set up the RecyclerView (phones)
RecyclerView recyclerViewLL = findViewById(R.id.recyclerView_list);
recyclerViewLL.setLayoutManager(new LinearLayoutManager(this));
adapterLL = new MyRecyclerViewAdapterLL(this, dataArray);
adapterLL.setClickListener(this);
recyclerViewLL.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
recyclerView.setAdapter(adapterLL);
// set up the RecyclerView (sw600dp)
RecyclerView recyclerViewGL = findViewById(R.id.recyclerView_list);
int numberOfColumns = 2;
recyclerViewGL.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
adapterGL = new MyRecyclerViewAdapterGL(this, dataArray);
adapterGL.setClickListener(this);
recyclerViewGL.setAdapter(adapterGL);
}
@Override
public void onItemClick(View view, int position) {
}
}
当前phone结果
以前使用的平板电脑代码 (sw600dp/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listview_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:stretchColumns="*"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TableRow
android:id="@+id/MainActivity_tableRow0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" >
<Button
android:id="@+id/MainActivity_btn0"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item A"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn1"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item B"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
<TableRow
android:id="@+id/MainActivity_tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" >
<Button
android:id="@+id/MainActivity_btn2"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item C"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn3"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item D"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
<TableRow
android:id="@+id/MainActivity_tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/MainActivity_btn4"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item E"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn5"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item G"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
</TableLayout>
预期的药片结果
当前平板电脑结果
values/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="my_boolean_value">true</bool>
</resources>
values-sw600dp/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="my_boolean_value">true</bool>
</resources>
您可以使用具有两个不同 LayoutManager
的 RecyclerView
(LinearLayout
和 GridLayout
)。
为了确定设备的大小,您需要评估一个布尔资源,您可以根据屏幕大小为其提供不同的值。
在res/values/bools.xml
<bool name="is_screen_small">true</bool>
在res/values-sw600dp/bools.xml
<bool name="is_screen_small">false</bool>
在 onCreate()
中,您使用 boolean
变量检索值,如下所示:
boolean isScreenSmall = getResources().getBoolean(R.bool.is_screen_small);
由于正确的值将由运行时传递给您,您可以使用它来设置具有正确 LayoutManager
:
的 RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView_list);
LayoutManager layoutManager;
if(isScreenSmall){
layoutManager = new LinearLayoutManager(this);
// maybe use special ItemDecoration for small devices
}
else{
int numberOfColumns = 2;
layoutManager = new GridLayoutManager(this, numberOfColumns);
// maybe use special ItemDecoration for large devices
}
recyclerView.setLayoutManager(layoutManager);
MyAdapter adapter = new MyAdapter(this, dataArray);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
请注意,我对两种屏幕尺寸使用相同的 RecyclerView
和 RecyclerView.Adapter
。如果我能保证列表项不会变得太宽(许多列表都是这种情况),这将起作用。
由于 "normal" 屏幕可能只有 320dp
宽,因此应该为 16dp
的左右边距留出空间("should" 因为 material design guidelines),无论如何,列表项的宽度不应超过 288dp
。但是在屏幕宽度为 600dp
的设备上,必须使用更宽的边距 (24dp
),因此应该将列表项的最大宽度设置为 270dp
,然后它们也适合进入具有两列的GridLayout
您还可以避免拥有大量布局文件,而是通过为不同的屏幕尺寸提供不同的尺寸值(边距、填充、宽度、高度等)来对布局进行一些微调。
为我的 activity 第一项使用相同的点击事件来调整布局的最有效方法是什么?我只看到 this and this 但他们没有完全解决问题。
当前phone代码 XML (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<ListView
android:id="@+id/my_listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Java
public class MainActivity extends Activity implements MyRecyclerViewAdapterGL.ItemClickListener, MyRecyclerViewAdapterLL.ItemClickListener {
MyRecyclerViewAdapterGL adapterGL;
MyRecyclerViewAdapterLL adapterLL;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// data to populate the RecyclerView with
String[] dataArray = {"Item A", "Item B", "Item C", "Item D" ,"Item E" ,"Item F"};
// set up the RecyclerView (phones)
RecyclerView recyclerViewLL = findViewById(R.id.recyclerView_list);
recyclerViewLL.setLayoutManager(new LinearLayoutManager(this));
adapterLL = new MyRecyclerViewAdapterLL(this, dataArray);
adapterLL.setClickListener(this);
recyclerViewLL.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
recyclerView.setAdapter(adapterLL);
// set up the RecyclerView (sw600dp)
RecyclerView recyclerViewGL = findViewById(R.id.recyclerView_list);
int numberOfColumns = 2;
recyclerViewGL.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
adapterGL = new MyRecyclerViewAdapterGL(this, dataArray);
adapterGL.setClickListener(this);
recyclerViewGL.setAdapter(adapterGL);
}
@Override
public void onItemClick(View view, int position) {
}
}
当前phone结果
以前使用的平板电脑代码 (sw600dp/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listview_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:stretchColumns="*"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TableRow
android:id="@+id/MainActivity_tableRow0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" >
<Button
android:id="@+id/MainActivity_btn0"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item A"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn1"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item B"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
<TableRow
android:id="@+id/MainActivity_tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" >
<Button
android:id="@+id/MainActivity_btn2"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item C"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn3"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item D"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
<TableRow
android:id="@+id/MainActivity_tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/MainActivity_btn4"
android:layout_column="0"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item E"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
<Button
android:id="@+id/MainActivity_btn5"
android:layout_column="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="start|center_vertical"
android:padding="30dp"
android:text="Item G"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
style="@style/TextAppearance.AppCompat.Large"
/>
</TableRow>
</TableLayout>
预期的药片结果
当前平板电脑结果
values/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="my_boolean_value">true</bool>
</resources>
values-sw600dp/bools.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="my_boolean_value">true</bool>
</resources>
您可以使用具有两个不同 LayoutManager
的 RecyclerView
(LinearLayout
和 GridLayout
)。
为了确定设备的大小,您需要评估一个布尔资源,您可以根据屏幕大小为其提供不同的值。
在res/values/bools.xml
<bool name="is_screen_small">true</bool>
在res/values-sw600dp/bools.xml
<bool name="is_screen_small">false</bool>
在 onCreate()
中,您使用 boolean
变量检索值,如下所示:
boolean isScreenSmall = getResources().getBoolean(R.bool.is_screen_small);
由于正确的值将由运行时传递给您,您可以使用它来设置具有正确 LayoutManager
:
RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView_list);
LayoutManager layoutManager;
if(isScreenSmall){
layoutManager = new LinearLayoutManager(this);
// maybe use special ItemDecoration for small devices
}
else{
int numberOfColumns = 2;
layoutManager = new GridLayoutManager(this, numberOfColumns);
// maybe use special ItemDecoration for large devices
}
recyclerView.setLayoutManager(layoutManager);
MyAdapter adapter = new MyAdapter(this, dataArray);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
请注意,我对两种屏幕尺寸使用相同的 RecyclerView
和 RecyclerView.Adapter
。如果我能保证列表项不会变得太宽(许多列表都是这种情况),这将起作用。
由于 "normal" 屏幕可能只有 320dp
宽,因此应该为 16dp
的左右边距留出空间("should" 因为 material design guidelines),无论如何,列表项的宽度不应超过 288dp
。但是在屏幕宽度为 600dp
的设备上,必须使用更宽的边距 (24dp
),因此应该将列表项的最大宽度设置为 270dp
,然后它们也适合进入具有两列的GridLayout
您还可以避免拥有大量布局文件,而是通过为不同的屏幕尺寸提供不同的尺寸值(边距、填充、宽度、高度等)来对布局进行一些微调。