Android 용 ListView 사용자 지정 컨트롤 만들기

가장 일반적으로 사용되며 가장 사용하기 어려운 control-ListView

ListView는 확실히 Android에서 가장 일반적으로 사용되는 컨트롤 중 하나입니다. 거의 모든 응용 프로그램에서이를 사용합니다.
ListView를 사용하면 화면의 원본 데이터가 화면 밖으로 스크롤되는 동안 손가락을 위아래로 밀어 화면 외부의 데이터를 화면으로 스크롤 할 수 있습니다.
그러나 ListView의 사용은 이전 컨트롤보다 비교적 복잡합니다.

새 프로젝트 ListViewTest

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
</LinearLayout>

ListView에는 일반적으로 두 가지 책임이 있습니다.
(1) 레이아웃에 데이터를 채 웁니다.
(2) 사용자의 선택, 클릭 및 기타 작업을 처리합니다.
ListView를 만들려면 세 가지 요소가 필요합니다.
(1) ListView의 각 열보기 (2) View의
데이터 또는 그림을 채 웁니다.
(3) 데이터와 ListView를 연결하기위한 어댑터.
즉, ListView를 사용하려면 먼저 어댑터가 무엇인지 이해해야합니다.
Adapter는 데이터와 AdapterView를 연결하는 브릿지입니다. (ListView는 일반적인 AdapterView입니다)
이를 통해 데이터와 AdaterView의 분리를 효과적으로 구현할 수있어 AndroidView와 데이터를보다 쉽고 편리하게 바인딩 할 수 있습니다.
Android에서 제공되는 많은 어댑터

어댑터 의미

ArrayAdapter는 배열을 바인딩하는 데 사용되며 일반 작업을 지원합니다.

SimpleAdapter는 xml에 정의 된 컨트롤에 해당하는 데이터를 바인딩하는 데 사용됩니다.

SimpleCursorAdapter는 커서로 얻은 데이터를 바인딩하는 데 사용됩니다.

BaseAdapter 범용베이스 어댑터

실제로 많은 어댑터가 있지만 변환 방법과 기능이 다를뿐 어댑터마다 다르다는 점에 유의해야합니다.

package net.nyist.lenovo.listviewtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {
    
    

private String[] data = {
    
    "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
        "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            MainActivity.this,android.R.layout.simple_list_item_1,data);
    ListView listView= (ListView)findViewById(R.id.list_view);
    listView.setAdapter(adapter);
}
}

ListView는 많은 양의 데이터를 표시하는 데 사용되므로 먼저 데이터를 제공해야합니다. 이러한 데이터는 특정 애플리케이션 시나리오에 따라 인터넷에서 다운로드하거나 데이터베이스에서 읽을 수 있습니다. 여기에서는 많은 과일의 이름을 포함하는 간단한 데이터 배열을 사용하여 테스트합니다.
그러나 배열의 데이터는 ListView로 직접 전달할 수 없으며 완료하려면 어댑터를 사용해야합니다.
ArrayAdpter에는 오버로드 된 생성자가 여러 개 있으며 실제 상황에 따라 적절한 생성자를 선택해야합니다.
우리가 제공하는 데이터는 모두 문자열이므로 ArrayAdapter의 일반 유형을 String으로 지정한 다음 현재 컨텍스트, LitView 하위 항목 레이아웃의 ID 및 ArrayAdapter의 생성자에서 조정할 데이터를 전달합니다. ListView 하위 항목 레이아웃의 ID로 android.R.layout.simple_list_item_1을 사용했습니다. 이것은 단순히 텍스트를 표시하는 데 사용할 수있는 TextView가 하나 뿐인 Android 내장 레이아웃 파일입니다. 이러한 방식으로 어댑터 개체가 구성됩니다.
마지막으로 ListView의 setAdapter () 메서드를 호출하여 생성 된 어댑터 개체를 전달해야 ListView와 데이터 간의 연결이 설정됩니다.
[외부 링크 이미지 전송에 실패했습니다. 소스 사이트에 안티 리치 링크 메커니즘이있을 수 있습니다. 이미지를 저장하고 직접 업로드하는 것이 좋습니다 (img-0I9U22qy-1587024879884) (http://i.imgur.com/xBKRLfV. png)] #Custom
ListView Interface
텍스트 한 단락 만 표시 할 수있는 ListView는 너무 단조롭 기 때문에 더 풍부한 콘텐츠를 표시 할 수 있도록 ListView의 인터페이스를 커스터마이즈 해 보겠습니다.
먼저 사진 세트를 준비해야합니다.
그런 다음 엔티티 클래스를 ListView 어댑터의 적응 유형으로 정의하십시오. 새 과일을 만듭니다. 코드는 다음과 같습니다.

package net.nyist.lenovo.listviewtest;
public class Fruit {
    
    
private String name;

private int imageId;

public Fruit(String name ,int imageId){
    
    
    this.name = name;
    this.imageId = imageId;
}

public int getImageId() {
    
    
    return imageId;
}

public String getName() {
    
    
    return name;
}
}

Fruit 클래스에는 두 개의 필드 만 있으며 name은 과일의 이름을 나타내고 imageId는 과일에 해당하는 이미지의 리소스 ID를 나타냅니다.
그런 다음 ListView의 자식에 대한 사용자 지정 레이아웃을 지정하고 레이아웃 디렉터리에 새로운 fruit_item.xml을 생성해야합니다. 코드는 다음과 같습니다.

<?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">

<ImageView
    android:id="@+id/fruit_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/fruit_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="10dp"
    />
</LinearLayout>

이 레이아웃에서는 과일 사진을 표시하는 ImageView를 정의하고 과일의 이름을 표시하는 TextView를 정의하고 TextView가 세로 방향의 중앙에 표시되도록합니다.

다음으로 ArrayAdapter에서 상속하는 사용자 지정 어댑터를 만들고 제네릭을 Fruit 클래스로 할당해야합니다. 새 클래스 FruitAdapter를 만듭니다. 코드는 다음과 같습니다.

package net.nyist.lenovo.listviewtest;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class FruitAdapter extends ArrayAdapter<Fruit>{
    
    

private int resourceId;

public FruitAdapter(Context context, int textViewResourceId, List<Fruit>objects){
    
    
    super(context,textViewResourceId,objects);
    resourceId = textViewResourceId;
}


@Override
public View getView(int position,  View convertView,  ViewGroup parent) {
    
    
    Fruit fruit = getItem(position);//获取当前项的Fruit实例
    View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
    ImageView fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
    TextView fruitName = (TextView)view.findViewById(R.id.fruit_name);
    fruitImage.setImageResource(fruit.getImageId());
    fruitName.setText(fruit.getName());
    return view;
}
}

// 레이아웃 관리자를로드하고 xml 레이아웃을 뷰 객체로 변환
View view = LayoutInflater.from (getContext ()). inflate (resourceId, parent, false);
// 뷰 객체를 사용하여 레이아웃
ImageView 에서 구성 요소 찾기 fruitImage = (ImageView) view.findViewById (R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById (R.id.fruit_name);
FruitAdapter
는 상위 클래스의 생성자 집합을 다시 작성하여 컨텍스트와 ListView 자식을 결합합니다. 레이아웃의 ID와 데이터가 전달됩니다.
또한 getView () 메서드가 다시 작성되며,이 메서드는 각 자식 항목이 화면으로 스크롤 될 때 호출됩니다. getView () 메서드에서 먼저 getItem () 메서드를 통해 현재 항목의 Fruit 인스턴스를 가져온 다음 LayoutInflater를 사용하여이 자식 항목에 대해 전달한 레이아웃을로드합니다.
여기서 LayoutInflater의 inflate () 메서드는 세 개의 매개 변수를받습니다. 처음 두 매개 변수의 의미를 이미 알고 있으며 세 번째 매개 변수는 false로 지정되어 있습니다. 즉, 부모 레이아웃에 선언 된 레이아웃 속성 만 유효하지만 이 View는 상위 레이아웃을 추가합니다. View에 상위 레이아웃이 있으면 더 이상 ListView에 추가 할 수 없기 때문입니다.
다음으로 View의 findViewById () 메서드를 호출하여 각각 ImageView 및 TextView의 인스턴스를 가져옵니다.
그리고 setImageResource () 및 setText () 메서드를 호출하여 표시된 그림과 텍스트를 설정하고 마지막으로 레이아웃을 반환하여 정의 된 어댑터가 완료되도록합니다.
MainActivity의 코드를 다음과 같이 수정합니다.

package net.nyist.lenovo.listviewtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    
    

private List<Fruit>fruitList = new ArrayList<>();



private String[] data = {
    
    "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
        "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initFruits();//初始化水果数据
    FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
    ListView listView= (ListView)findViewById(R.id.list_view);
    listView.setAdapter(adapter);
}
private void initFruits(){
    
    
    for (int i  = 0;i < 2;i++){
    
    
        Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
        fruitList.add(apple);
        Fruit banana = new Fruit("Banana",R.drawable.banana_pic);
        fruitList.add(banana);
        Fruit orange = new Fruit("Orange",R.drawable.orange_pic);
        fruitList.add(orange);
        Fruit watermelon = new Fruit("Watermelon",R.drawable.watermelon_pic);
        fruitList.add(watermelon);
        Fruit pear = new Fruit("Pear",R.drawable.pear_pic);
        fruitList.add(pear);
        Fruit grape = new Fruit("Grape",R.drawable.grape_pic);
        fruitList.add(grape);
        Fruit pineapple = new Fruit("Pineapple",R.drawable.pineapple_pic);
        fruitList.add(pineapple);
        Fruit strawberry = new Fruit("Strawberry",R.drawable.strawberry_pic);
        fruitList.add(strawberry);
        Fruit cherry = new Fruit("Cherry",R.drawable.cherry_pic);
        fruitList.add(cherry);
        Fruit mango = new Fruit("Mango",R.drawable.mango_pic);
        fruitList.add(mango);

    }
}
}

여기에 initFruits () 메서드를 추가하여 모든 과일 데이터를 초기화합니다. Fruit 클래스의 생성자에서 과일의 이름과 해당 이미지 ID를 전달한 다음 생성 된 객체를 과일 목록에 추가합니다. 또한 for 루프를 사용하여 모든 과일 데이터를 두 번 추가합니다. 한 번만 추가하면 데이터 양이 전체 화면을 채울만큼 충분하지 않은 경우 onCreate () 메서드에서 FruitAdpter 개체가 생성되고 FruitAdapter가 어댑터로 ListView에 전달되므로 사용자 지정 작업이 ListView 인터페이스가 완료되었습니다.

여기에 사진 설명 쓰기

#ListView의 클릭 이벤트 그런데 ListView의
스크롤은 결국 우리의 시각 효과를 만족시킬 뿐이지 만 ListView의 자식 항목을 클릭 할 수없는 경우이 컨트롤은 실용적이지 않습니다. 따라서이 섹션에서는 ListView가 사용자 클릭 이벤트에 응답하는 방법에 대해 알아 봅니다.
MainActivity의 코드를 다음과 같이 수정합니다.

public class MainActivity extends AppCompatActivity {
    
    

private List<Fruit>fruitList = new ArrayList<>();
private String[] data = {
    
    "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
        "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initFruits();//初始化水果数据
    FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
    ListView listView= (ListView)findViewById(R.id.list_view);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
    
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
    
            Fruit fruit = fruitList.get(position);
            Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();
        }
    });
}

보시다시피 setOnItemClickListener () 메서드를 사용하여 ListView에 대한 리스너를 등록하고 사용자가 ListView에서 자식 항목을 클릭하면 onItemClick () 메서드가 다시 호출됩니다. 이 방법에서는 위치 매개 변수를 사용하여 사용자가 클릭 한 하위 항목을 확인한 다음 해당 과일을 얻을 수 있으며, 과일의 이름은 Toast를 통해 표시 할 수 있습니다.

추천

출처blog.csdn.net/i_nclude/article/details/75263636