“This is the sixth day of my participation in the First Challenge 2022. For details: First Challenge 2022”
In this third blog post in the Custom View series, we will learn how to implement a custom drop-down box.Today’s program, we will achieve such an effect.The layout is very simple and we just start coding. Modify the code of the activity_main.xml file.
<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="com.itcast.test0430.MainActivity">
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:hint="Please enter the content..."
android:paddingRight="40dp"
android:singleLine="true" />
<ImageView
android:id="@+id/iv_down_arrow"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignRight="@id/et_input"
android:layout_alignTop="@id/et_input"
android:padding="5dp"
android:src="@drawable/down_arrow" />
</RelativeLayout>
Copy the code
The layout code is very simple, just two controls. Next, modify the MainActivity code.
package com.itcast.test0430;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.et_input)
EditText etInput;
@BindView(R.id.iv_down_arrow)
ImageView ivDownArrow;
/ * * * * /
private PopupWindow popupWindow;
private ListView listView;
private ArrayList<String> msgs;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
listView = new ListView(this);
listView.setBackgroundColor(Color.WHITE);
// Prepare data
msgs = new ArrayList<>();
for(int i = 0; i <500; i++) { msgs.add(i +"--aaaaaa---" + i);
}
adapter = new MyAdapter();
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<? > parent, View view,int position, long id) {
//1
String msg = msgs.get(position);
//2, set to input box
etInput.setText(msg);
if(popupWindow ! =null && popupWindow.isShowing()){
popupWindow.dismiss();
popupWindow = null; }}}); }@OnClick(R.id.et_input)
public void onViewClick(View view){
if(popupWindow == null){
popupWindow = new PopupWindow(this);
popupWindow.setWidth(etInput.getWidth());
popupWindow.setHeight(400);
popupWindow.setContentView(listView);
popupWindow.setFocusable(true);// Set the focus
}
popupWindow.showAsDropDown(etInput,0.0);
}
class MyAdapter extends BaseAdapter{
@Override
public int getCount(a) {
return msgs.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
convertView = View.inflate(MainActivity.this,R.layout.item_main,null);
viewHolder = new ViewHolder();
viewHolder.tv_msg = convertView.findViewById(R.id.tv_msg);
viewHolder.iv_delete = convertView.findViewById(R.id.iv_delete);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
// Get data based on location
final String msg = msgs.get(position);
viewHolder.tv_msg.setText(msg);
// Set delete
viewHolder.iv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// delete from collection
msgs.remove(msg);
// Refresh the UI-- refresh the adapteradapter.notifyDataSetChanged(); }});returnconvertView; }}static class ViewHolder{ TextView tv_msg; ImageView iv_delete; }}Copy the code
The code for the item_main.xml file is as follows.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:padding="3dp"
android:src="@drawable/user" />
<TextView
android:id="@+id/tv_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:layout_weight="1"
android:gravity="center"
android:padding="3dp"
android:text="The Three Musketeers"
android:textColor="# 000" />
<ImageView
android:id="@+id/iv_delete"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:padding="3dp"
android:src="@drawable/delete" />
</LinearLayout>
Copy the code
The code here is also very simple, so I won’t explain too much, and there are comments everywhere. Only need to pay attention to is that, because our PopupWindow class is set up for 200 wide, and as long as it is in the code set control properties, its unit of px (pixels), the pixel is no adaptation function, so in order to make our program can run correctly on any resolution of the mobile phone, we should convert pixels to dp. A utility class is provided for converting between DP and PX.
package com.itcast.test0430;
import android.content.Context;
public class DensityUtil {
/** * Convert dip units to px(pixels) */ based on the resolution of the phone
public static int dipToPx(Context context,float dpValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5 f);
}
/** * Convert from px(pixels) to dip */ based on the phone's resolution
public static int pxToDip(Context context,float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue * scale + 0.5 f); }}Copy the code
So, we put popupwindow.setheight (400); Instead of
int height = DensityUtil.dipToPx(this.400);
popupWindow.setHeight(height);
Copy the code
Can. Now run the project to get a preview.In this way, our drop-down box is also implemented. Now that we have a utility class for converting between DP and PX, we can use it where screen adaptation is needed, including some of the projects we practiced earlier.
The source has been uploaded to GitHub