求助:在基于地点搜索的献血者ListView中添加呼叫按钮
Hey there! Let's get that call button up and running in your ListView entries—here's a straightforward, step-by-step guide tailored to your project setup:
Step 1: Update Your List Item Layout
First, open the layout file for your ListView items (e.g., list_item_blood_donor.xml) and add a call button next to the phone number TextView (bld_phn). Here's what the updated layout might look like:
<!-- Existing views for name, blood type, phone number --> <TextView android:id="@+id/bld_phn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Phone Number"/> <!-- Add this call button --> <Button android:id="@+id/call_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Call" android:layout_marginStart="16dp"/>
Step 2: Create a Custom Adapter with Button Click Handling
Since you're using a ListView, you'll need a custom Adapter to handle the button's click event for each item. This example uses BaseAdapter (you can adapt it to ArrayAdapter if you prefer):
public class DonorAdapter extends BaseAdapter { private Context context; private JSONArray donorData; // Matches your jarray from the Activity public DonorAdapter(Context context, JSONArray donorData) { this.context = context; this.donorData = donorData; } @Override public int getCount() { return donorData.length(); } @Override public Object getItem(int position) { try { return donorData.getJSONObject(position); } catch (JSONException e) { e.printStackTrace(); return null; } } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // Use ViewHolder pattern for better performance if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.list_item_blood_donor, parent, false); holder = new ViewHolder(); holder.phoneTextView = convertView.findViewById(R.id.bld_phn); holder.callButton = convertView.findViewById(R.id.call_btn); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // Populate data for the current item try { JSONObject donor = donorData.getJSONObject(position); String phoneNumber = donor.getString("phone"); // Match your server's key for phone holder.phoneTextView.setText(phoneNumber); // Set click listener for the call button holder.callButton.setOnClickListener(v -> { // Check for CALL_PHONE permission (critical for Android 6.0+) if (ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { // Request permission if not granted ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CALL_PHONE}, 100); return; } // Launch the dialer to call the donor Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:" + phoneNumber)); context.startActivity(callIntent); }); } catch (JSONException e) { e.printStackTrace(); } return convertView; } // ViewHolder class to cache views static class ViewHolder { TextView phoneTextView; Button callButton; } }
If you're using a String[] phone array instead of a JSONArray, adjust the Adapter to accept the array and fetch the number with phone[position] instead of parsing JSON.
Step 3: Set the Adapter in Your blood Activity
In your blood Activity, after fetching the donor data with AsyncHttpClient, initialize the adapter and attach it to your ListView:
// Inside your AsyncHttpClient's onSuccess callback client.get("your_api_endpoint_url", new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, JSONArray response) { super.onSuccess(statusCode, headers, response); jarray = response; // Initialize and set the adapter DonorAdapter donorAdapter = new DonorAdapter(blood.this, jarray); yourListView.setAdapter(donorAdapter); // Replace with your ListView instance } @Override public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { super.onFailure(statusCode, headers, responseString, throwable); // Handle error cases (e.g., show a toast) } });
Step 4: Add Required Permissions
Don't forget to add the CALL_PHONE permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.CALL_PHONE"/>
For Android 6.0 (API level 23) and above, the code already handles dynamic permission requests, so users will see a prompt to allow calls when they first tap the button.
That's it! Each ListView item will now have a functional call button that launches the dialer with the donor's phone number.
内容的提问来源于stack exchange,提问作者Azhar Saeed

