Android应用关于页应使用何种Layout XML布局?
Got it, let's tackle this about screen problem you're having—totally get why Preference XML feels overkill when you just need to display static info and add a few simple interactive links (like open-source licenses or TOS). Google's about screens are clean and focused, and we can replicate that using basic Android UI components without the preference framework. Here's a step-by-step solution:
Google's about screens typically follow a pattern:
- Top section with app icon, name, and version number
- A list of interactive entries (licenses, TOS) or static text
- Clean, consistent styling with ripple effects on clickable items
1. Layout Setup
First, create the main about screen layout (activity_about.xml). We'll use a RecyclerView for the interactive entries to keep things scalable:
<?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="match_parent" android:orientation="vertical"> <!-- App Info Header --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/app_icon" android:layout_width="64dp" android:layout_height="64dp" android:src="@mipmap/ic_launcher_round"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" android:textSize="20sp" android:textStyle="bold" android:layout_marginTop="8dp"/> <TextView android:id="@+id/tv_version" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="@android:color/darker_gray" android:layout_marginTop="4dp"/> </LinearLayout> <!-- Divider --> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/darker_gray" android:alpha="0.1"/> <!-- Interactive Entries --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_about_items" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
Next, create a reusable list item layout (item_about_entry.xml) for each entry:
<?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:paddingHorizontal="16dp" android:paddingVertical="12dp" android:orientation="horizontal" android:gravity="center_vertical" android:background="?android:attr/selectableItemBackground"> <!-- Adds Google-style ripple effect --> <TextView android:id="@+id/tv_title" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:textSize="16sp"/> <!-- Arrow for clickable items --> <ImageView android:id="@+id/iv_arrow" android:layout_width="24dp" android:layout_height="24dp" android:src="@drawable/ic_arrow_right" android:visibility="gone"/> </LinearLayout>
2. Data & Adapter Setup
Create a data class to hold each entry's details:
data class AboutItem( val title: String, val isClickable: Boolean, val action: () -> Unit // Lambda for click behavior )
Then build a RecyclerView adapter to bind these items:
class AboutAdapter(private val items: List<AboutItem>) : RecyclerView.Adapter<AboutAdapter.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvTitle: TextView = itemView.findViewById(R.id.tv_title) val ivArrow: ImageView = itemView.findViewById(R.id.iv_arrow) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_about_entry, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = items[position] holder.tvTitle.text = item.title // Show arrow and enable click only for interactive items if (item.isClickable) { holder.ivArrow.visibility = View.VISIBLE holder.itemView.setOnClickListener { item.action.invoke() } } else { holder.ivArrow.visibility = View.GONE holder.itemView.isClickable = false } } override fun getItemCount() = items.size }
3. Initialize the About Activity
In your AboutActivity, set up the header (including version number) and populate the RecyclerView:
class AboutActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_about) // Set app version number val versionName = packageManager.getPackageInfo(packageName, 0).versionName findViewById<TextView>(R.id.tv_version).text = "Version $versionName" // Define about screen entries val aboutItems = listOf( AboutItem("Open-source licenses", true) { // Navigate to licenses screen (we'll build this next) startActivity(Intent(this, OpenSourceLicensesActivity::class.java)) }, AboutItem("Terms of Service", true) { // Open TOS in a web view or browser val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://your-tos-url.com")) startActivity(intent) }, AboutItem("Privacy Policy", true) { // Open privacy policy similarly }, AboutItem("Built with ❤️", false) {} // Static non-clickable text ) // Set up RecyclerView val recyclerView = findViewById<RecyclerView>(R.id.rv_about_items) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = AboutAdapter(aboutItems) } }
4. Add the Open-Source Licenses Screen
For the licenses page, use a WebView to display a pre-written HTML file (store it in src/main/assets/open_source_licenses.html):
<!-- activity_open_source_licenses.xml --> <?xml version="1.0" encoding="utf-8"?> <WebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent"/>
Then in the activity:
class OpenSourceLicensesActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_open_source_licenses) // Add back button to action bar supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.title = "Open-source licenses" // Load local HTML file findViewById<WebView>(R.id.web_view).loadUrl("file:///android_asset/open_source_licenses.html") } override fun onSupportNavigateUp(): Boolean { finish() return true } }
Alternative: No RecyclerView (For Smaller Screens)
If you only have a few entries, you can skip RecyclerView and use a vertical LinearLayout with hardcoded items. Each clickable item would have an android:onClick attribute pointing to a method in your activity.
This approach gives you full control over the UI, matches Google's clean about screen style, and avoids the unnecessary overhead of Preference XML when you don't need preference management.
内容的提问来源于stack exchange,提问作者crazo7924

