Android studio的ListView:

ListView比之前的要难一些,因为要做一个item的模子。就要新建一个他的xml文件在layout里面:

那我们首先和往常一样我们新建一个按钮:

<Button

    android:id=”@+id/ListView”

    android:layout_width=”match_parent”

    android:layout_height=”wrap_content”

    android:layout_marginTop=”5dp”

    android:background=”#ccff00″

    android:text=”ListView”

    android:textAllCaps=”false”

    android:textSize=”25sp” />

然后再去声明并添加跳转页面和事件:

然后去添加的新页面中新建一个Litsview:

<ListView

        android:id=”@+id/lv”

        android:layout_width=”match_parent”

        android:layout_height=”wrap_content”

        android:listSelector=”@drawable/liststyle”

        android:divider=”@color/orange”

        android:dividerHeight=”5dp”

        android:paddingBottom=”2dp”

        >

    </ListView>

</RelativeLayout>

<!–android:listSelector=”@drawable/liststyle”这个是用来设置点击效果的–>

<!–    android:divider=”@color/orange”这个为线的颜色–>

<!–    android:dividerHeight=”5dp”分隔线的宽度–>

截屏2020-02-17下午5.46.59.png

然后我们会发现我们里面的item要怎么添加呢我们就要去到java文件里:

和之前一样我们先把ListView声明。

然后findID找到后我们。

要通过一个叫setAdapter方法来设置。

listView.setAdapter(new list_Adapter(ListViewActivity.this));

截屏2020-02-17下午5.51.00.png

查看源代码我们可以看到我们的方法里要填一个ListAdapter adapter。

那我们就自己新建一个:

首先我们新建一个list_Adapter的java文件让他继承于BaseAdapter:

public class list_Adapter extends BaseAdapter

在继承了他的方法了之后

这样我们就有了一个ListAdapter的class了:

截屏2020-02-17下午5.54.17.png

我们首先把我们新建的list_Adapter给写个构造器:

public class list_Adapter extends BaseAdapter {

    private Context context;

    private LayoutInflater layoutInflater;

    public list_Adapter(Context context){

        this.context = context;

        layoutInflater = LayoutInflater.from(context);

    }

//这里的的Context context这个变量用来传入一个Acitvity

我也不知道为什么。会是这个。

然后在初始化一个LayoutInflater。用这个方法把他赋值了LayoutInflater.from(context);

在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。

不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;

而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。

截屏2020-02-17下午6.05.04.png

LayoutInflater布局充气机。

然后我们去layout新建一个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”

    android:descendantFocusability=”blocksDescendants”

    android:orientation=”horizontal”

    android:padding=”20dp”>

    <ImageView

        android:id=”@+id/iv”

        android:layout_width=”150dp”

        android:layout_height=”150dp”

        android:background=”#C4C4C4″

        android:scaleType=”centerCrop”

        android:src=”@drawable/flygirl” />

    <LinearLayout

        android:layout_width=”match_parent”

        android:layout_height=”match_parent”

        android:orientation=”vertical”

        android:padding=”10dp”>

        <TextView

            android:id=”@+id/tvtitle”

            android:layout_width=”wrap_content”

            android:layout_height=”wrap_content”

            android:text=”This is title”

            android:textColor=”#000000″

            android:textSize=”25sp” />

        <TextView

            android:id=”@+id/tvdata”

            android:layout_width=”wrap_content”

            android:layout_height=”wrap_content”

            android:layout_marginTop=”10dp”

            android:text=”2020/10/10″

            android:textColor=”#C4C4C4″

            android:textSize=”18sp” />

        <TextView

            android:id=”@+id/et”

            android:layout_width=”match_parent”

            android:layout_height=”61dp”

            android:layout_marginTop=”10dp”

            android:hint=”this is content”

            android:singleLine=”true” />

    </LinearLayout>

</LinearLayout>

截屏2020-02-17下午8.08.18.png

干完了之后我们就回到我们的

Adapter文件去:

package com.example.myfirstapplication.Listview;

import android.content.Context;

import android.media.TimedText;

import android.os.Build;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.EditText;

import android.widget.ImageView;

import android.widget.TextView;

import androidx.annotation.RequiresApi;

import com.example.myfirstapplication.R;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

public class list_Adapter extends BaseAdapter {

    private Context context;

    private LayoutInflater layoutInflater;

    public list_Adapter(Context context){

        this.context = context;

        layoutInflater = LayoutInflater.from(context);

    }

    @Override

    public int getCount() {

        return 10;

        //这里必须要填,不填会导致没有显示。

    }

    @Override

    public Object getItem(int position) {

        return null;

    }

    @Override

    public long getItemId(int position) {

        return 0;

    }

    static class ViewHold

    {

        public ImageView iv;

        public TextView tvtitle,tvdate,et;

//        private EditText et;

    }

    @RequiresApi(api = Build.VERSION_CODES.O)

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHold h = null;

        if (convertView == null) {

            convertView = layoutInflater.inflate(R.layout.once_listview, null);

            //layoutInflater对象就是用来在这里inflate(R.layout.once_listview,null);用这个方法来赋值给convertView

            //·inflate 是用来找 res/layout 下的 xml 布局文件,并且实例化的;

            h = new ViewHold();

            h.iv = convertView.findViewById(R.id.iv);

            h.tvtitle = convertView.findViewById(R.id.tvtitle);

            h.tvdate = convertView.findViewById(R.id.tvdata);

            h.et = convertView.findViewById(R.id.et);

            convertView.setTag(h);

            //setTag()getTag()方法常用在处理多个相同的View

            //为了提高程序性能,我们在给ListView写适配器Adapter的时候,我们就要用到Tag

            //这里有点不理解

        }else {

            h = (ViewHold) convertView.getTag();

        }

        //setTag()用于给View添加额外的数据,可以使用getTag()方法获取出这个额外的数据。

        //在此段代码中,我们把控件的实例都缓存在了ViewHolder中,就没有必要每次都通过findviewbyid获取实例。

        //————————————————————————//

        /首先我们要知道setTag方法是干什么的,他是给View对象的一个标签,标签可以是任何内容,我们这里把他设置成了一个对象,因为我们是把xml的元素抽象出来成为一个类ViewHolder,用了setTag,这个标签就是ViewHolder实例化后对象的一个属性。我们之后对于ViewHolder实例化的对象holder的操作,都会因为java的引用机制而一直存活并改变convertView的内容,而不是每次都是去new一个。我们就这样达到的重用。

/给控件赋值:

        //这里调用了setText之后我们之前设置的texview的文字都会被覆盖的,也可以不写,就会调用原来的text

        LocalDateTime dateTime = LocalDateTime.now();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“dd-MM-yyyy HH:mm:ss”);

        //这个获取当前时间的方法。

        h.tvtitle.setText(“Title”);

        h.tvdate.setText(dateTime.format(formatter));

        h.et.setText(“content!!”);

        return convertView;

    }

}

这有点难要看久一点。

然后回到activity.java去

listView.setAdapter(new list_Adapter(ListViewActivity.this));

把我们的Adapter填进去。

截屏2020-02-17下午8.12.04.png

事件:

有两种:

1)短按:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override

            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Toast.makeText(ListViewActivity.this,“Click POS”+position,Toast.LENGTH_LONG).show();

            }

        });

2)长按:

        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override

            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                Toast.makeText(ListViewActivity.this,“LongClick POS”+position,Toast.LENGTH_LONG).show();

                return true;

                //这里的返回值是判断我们要不要继续执行的。我们可以这样他就会在我们长按结束后继续执行,那就会到短按了。

                //我们只要把返回的改为true就好了。

            }

        });

    }

}

//我在设置listview的时候我遇到了我的子类item中的editview把父类的item抢夺了。

目前我还没有找到对EditView的解决方案。

//导致我在设置了listview的点击效果的时候无效被抢夺了

//这里有三种解决方案

//

//        1.ListView中的Item布局中的子控件focusable属性设置为false

//        2.getView方法中设置button.setFocusable(false)

//

//        3.设置item的根布局的属性android:descendantFocusability=”blocksDescendant”

//

//        我们可以发现,其实这三种方法都是为了让Button等控件不能获取焦点,从而使得item可以响应点击事件。

//

//        第三种方法使用起来相对方便,因为它是将item布局中的其他所有控件都设置为不能获取焦点。

//

//        android:descendantFocusability属性共有三个取值,分别为

//

//        beforeDescendantsviewgroup会优先其子类控件而获取到焦点

//        afterDescendantsviewgroup 只有当其子类控件不需要获取焦点时才获取焦点

//        blocksDescendantsviewgroup 会覆盖子类控件而直接获得焦点

最后修改日期:2020年2月21日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。