简体   繁体   English

如何为SimpleCursorAdapter编写公共类?

[英]how can i code public class for SimpleCursorAdapter?

I am new to android and I need to use ListView for my project. 我是android新手,我需要为项目使用ListView I use a sample from the internet which has no public class for ListView so I am not able to code flexible. 我使用的是Internet上没有ListView公共类的示例,因此我无法灵活编写代码。 how can I code public class for this. 我如何为此编写公共课程。

public class LIGHTS extends AppCompatActivity {

    ListView users_list;
    private DatabaseManager dbManager;
    private SimpleCursorAdapter adapter;
    private DatabaseHelper dbHelper;

    final String[] from = new String[]{dbHelper._ID, dbHelper.TITLE, dbHelper.DESC};
    final int[] to = new int[]{R.id.id, R.id.KEYCODE, R.id.NAME};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lights);
        startconnection();

        dbManager = new DatabaseManager(this);
        dbManager.open();
        Cursor cursor = dbManager.fetch();

        users_list = findViewById(R.id.users_list);

        adapter = new SimpleCursorAdapter(this, R.layout.adapter, cursor, from, to, 0);
        users_list.setAdapter(adapter);}

and the fetch() is in below code in dbmanager: 而fetch()在dbmanager中的以下代码中:

    public Cursor fetch() {
        String[] columns = new String[]{dbHelper._ID, dbHelper.TITLE, dbHelper.DESC};
        Cursor cursor = database.query(dbHelper.TABLE_NAME, columns, null, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        return cursor;
    }

In order to customize a ListAdapter, you need to create your own custom ListAdapter class that is based on, or 'extends' the built-in ListAdapter (such as SimpleListAdapter or BaseAdapter). 为了自定义ListAdapter,您需要创建自己的自定义ListAdapter类,该类基于或“扩展”内置的ListAdapter(例如SimpleListAdapter或BaseAdapter)。 Then, you can customize the appearance and what fields of data to display. 然后,您可以自定义外观以及要显示的数据字段。 Below is an example of a custom ListAdapter I called ClaimsListAdapter.java that 'extends' the built-in class called BaseAdapter: 以下是我称为ClaimsListAdapter.java的自定义ListAdapter的示例,该列表适配器“扩展”了称为BaseAdapter的内置类:

package com.mycompany.myapp.adapter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.mycompany.myapp.ClaimListFragment;
import com.mycompany.myapp.R;
import com.mycompany.myapp.TripListFragment;
import com.mycompany.myapp.model.ClaimItem;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

// You might be able to extend SimpleListAdapter instead if you wish
public class ClaimListAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<ClaimItem> claimItems;
    ClaimListFragment fragment;

    //I'm passing references to both the active Context as well as the active Fragment
    //You might only need to pass the active Context
    public ClaimListAdapter(ClaimListFragment fragment, Context context, ArrayList<ClaimItem> claimItems){
        this.context = context;
        this.claimItems = claimItems;
        this.fragment = fragment;
    }

    @Override
    public int getCount() {
        return claimItems.size();
    }

    @Override
    public Object getItem(int position) {       
        return claimItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater)
                    context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            //This is the layout for the list item.  A SimpleListAdapter doesn't need one
            //since it only has one text view, but this allows you to create multiple lines
            //and/or multiple fields, buttons, checkboxes etc if you wish
            convertView = mInflater.inflate(R.layout.claim_list_item, null);
        }

        //Get a reference to all of the items in the layout you wish to change
        Button btnDelete = (Button) convertView.findViewById(R.id.claim_delete_in_list);
        //Note, here I'm saving the row number in the tag of the button to tell the fragment
        //which row in the array to delete.
        btnDelete.setTag(position);
        //Here is an example of setting a click listener for a button in the list
        btnDelete.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Integer position = (Integer)v.getTag();
                //Call the Public method in the parent Fragment (or Activity) to delete from the
                //array and refresh the list
                fragment.deleteItemList(position);
            }
        });

        btnDelete.setVisibility(View.GONE);

        //Get a reference to all of the text fields in the list item
        TextView txtTitle = (TextView) convertView.findViewById(R.id.claim_title);
        TextView txtStatus = (TextView) convertView.findViewById(R.id.claim_status);
        TextView txtDate = (TextView) convertView.findViewById(R.id.claim_date);
        TextView txtDistance = (TextView) convertView.findViewById(R.id.claim_distance);
        TextView txtAmount = (TextView) convertView.findViewById(R.id.claim_amount);

        String claim_title = claimItems.get(position).getDocumentID();
        String claim_status = claimItems.get(position).getClaimStatus();

        txtTitle.setText(claim_title);
        txtStatus.setText(claim_status);

        return convertView;
    }

}

And the claim_list_item.xml layout file: 和Claim_list_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="wrap_content" 
    android:baselineAligned="false"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/whole_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.7"
        android:background="@drawable/list_selector_light"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/top_layout"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:layout_weight="0.48"
            android:background="#00000000"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/claim_title"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:layout_marginBottom="2dp"
                android:layout_marginLeft="5dp"
                android:layout_marginStart="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginEnd="5dp"
                android:layout_weight="0.73"
                android:background="#00000000"
                android:gravity="start|center_vertical"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/claim_status"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginBottom="2dp"
                android:layout_marginEnd="5dp"
                android:layout_marginRight="5dp"
                android:background="#00000000"
                android:gravity="end|center_vertical"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="14sp" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/bottom_layout"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:layout_weight="0.48"
            android:background="#00000000"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/claim_date"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginLeft="5dp"
                android:layout_marginStart="5dp"
                android:background="#00000000"
                android:gravity="start|center_vertical"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/claim_distance"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="50dp"
                android:layout_marginStart="50dp"
                android:layout_marginRight="50dp"
                android:layout_marginEnd="50dp"
                android:layout_weight="1.0"
                android:layout_gravity="center"
                android:background="#00000000"
                android:gravity="center|center_vertical"
                android:text=""
                android:textSize="12sp"
                android:textColor="#FFFFFFFF"/>

            <TextView
                android:id="@+id/claim_amount"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginBottom="2dp"
                android:layout_marginEnd="5dp"
                android:layout_marginRight="5dp"
                android:background="#00000000"
                android:gravity="end|center_vertical"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="12sp" />

         </LinearLayout>
     </LinearLayout>

     <Button
        android:id="@+id/claim_delete_in_list"
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:layout_weight="0.3"
        android:text="@string/delete"
        android:textSize="16sp"
        android:textColor="#FFFFFFFF"
        android:background="@android:color/holo_red_dark"
        />

</LinearLayout>

Here's an example based upon your code that handles clicking a button for each item in the list. 这是一个基于您的代码的示例,该代码处理单击列表中每个项目的按钮。

If you click a switch then it displays the id of the item via a toast. 如果单击开关,则它会通过烤面包来显示商品的ID。

This utilises a Custom Adapter based upon (extends) the CursorAdapter class. 这利用了基于(扩展)CursorAdapter类的自定义适配器。

First the layout adapter.xml used for the item (should have the basics of your's and includes a switch who's id is the_switch) :- 首先,用于该项目的布局adapter.xml (应该具有您的基础知识,并包括ID为the_switch的开关):-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/id"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/KEYCODE"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/NAME"
        android:layout_width="0dp"
        android:layout_weight="6"
        android:layout_height="wrap_content" />
    <Switch
        android:id="@+id/the_switch"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:focusable="false"
        />
</LinearLayout>

The Activity Lights.java is now :- Activity Lights.java现在是:-

public class Lights extends AppCompatActivity {

    ListView users_list, alt_users_list;
    private DatabaseManager dbManager;
    private MyCustomCursorAdapter adapter;
    //private DatabaseManager dbHelper; //?????? a second not needed
    Cursor cursor;
    Context mContext;

    //<<<<<<<<<< Not needed although could be passed
    //final String[] from = new String[]{DatabaseManager._ID, DatabaseManager.TITLE, DatabaseManager.DESC};
    //final int[] to = new int[]{R.id.id, R.id.KEYCODE, R.id.NAME};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        setContentView(R.layout.activity_lights);
        startconnection(); //?????? dummied out
        users_list = findViewById(R.id.users_list);
        alt_users_list = findViewById(R.id.alt_users_list);

        dbManager = new DatabaseManager(this);
        dbManager.open();
        manageListView(); //Handles the ListView
    }

    // Moved here handles list refresh if called (e.g. in onResume)
    private void manageListView() {
        cursor = dbManager.fetch();
        //Setup the adapter if not already setup else swaps (refreshes) the cursor
        if (adapter == null) {
            adapter = new MyCustomCursorAdapter(this, cursor);
            users_list.setAdapter(adapter);
            users_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(mContext,"You clicked on the item with an ID of " + String.valueOf(id),Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            adapter.swapCursor(cursor);
        }
    }
    private void startconnection(){}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Close the Cursors when done with them
        cursor.close();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Refresh the listviews when returning to the activity
        manageListView();
    }
}
  • Comments try to explain changes (basically it is quite similar). 注释试图解释更改(基本上是非常相似的)。
  • The biggest change is that the setting up of the listview has been moved to a method of it's own, which also handles refreshing the listview (redisplaying it after the underlying data has been changed). 最大的变化是列表视图的设置已移至它自己的方法,该方法还处理刷新列表视图(在基础数据更改后重新显示)。
  • The instantiation of the adapter is also simpler than for the SimpleCursorAdapter (the layout and column to view handling coded in the adapter). 适配器的实例化也比SimpleCursorAdapter简化(用于查看适配器中编码的处理的布局和列)。

The adapter myCustomAdapter.java is :- 适配器myCustomAdapter.java是:-

public class MyCustomCursorAdapter extends CursorAdapter {

    public MyCustomCursorAdapter(Context context, Cursor c) {
        super(context, c, 0);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        if (position % 2 == 0) {
            view.setBackgroundColor(0xFFAAAAFF);
        } else {
            view.setBackgroundColor(0xAAAAAAFF);
        }
        return view;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.adapter,parent,false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ((TextView)view.findViewById(R.id.id)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager._ID)));
        ((TextView)view.findViewById(R.id.KEYCODE)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager.TITLE)));
        ((TextView)view.findViewById(R.id.NAME)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager.DESC)));

        Switch thisswitch = view.findViewById(R.id.the_switch);
        thisswitch.setTag(cursor.getString(cursor.getColumnIndex(DatabaseManager._ID)));
        thisswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Toast.makeText(buttonView.getContext(),
                        "You clicked the switch for ID " + (String) buttonView.getTag() +
                                " the status is now " + (new Boolean(isChecked)).toString(),
                        Toast.LENGTH_SHORT)
                        .show()
                ;
            }
        });
    }
}
  • bindView has primarily been used it :- bindView主要用于它:
    • binds the values from the columns of the cursor to the views for each item 将光标列中的值绑定到每个项目的视图
    • and in this case sets the tag of the switch to the id and then adds an onCheckChangedListener for the Button. 在这种情况下,将开关的标签设置为id,然后为Button添加一个onCheckChangedListener。
  • bindView has the advantage that the cursor and context are passed to it. bindView的优点是将游标和上下文传递给它。
  • getView can also be used, it has the advantage of having the position of the item in the list passed. 也可以使用getView,它具有传递项目在列表中的位置的优点。
  • In this case it has been used to alternate the background colour for each item. 在这种情况下,已使用它来替换每个项目的背景颜色。

Result 结果

Here's a screen shot showing the toast (note testing data was added to the underlying database, so this will obviously vary from yours) :- 这是显示吐司的屏幕截图(注意测试数据已添加到基础数据库中,因此显然与您的不同):

在此处输入图片说明

Additional 额外

It might be that you need to handle the switch check change in the owning activity. 可能是您需要处理拥有活动中的开关检查更改。

The following changes show a basic means, via an interface, of handling the switch event in the activity, rather than in the adapter. 以下更改显示了通过接口处理活动而不是适配器中的switch事件的基本方法。

First the interface myOnCheckedChangedInterface.java 首先,接口myOnCheckedChangedInterface.java

public interface myOnCheckedChangedInterface {
    void myOnCheckedChangedHandler(String id, boolean check_status);
}

Second change Lights.java by adding the handler method myOnCheckedChangedHandler 通过增加处理方法myOnCheckedChangedHandler第二个变化Lights.java

@Override
public void myOnCheckedChangedHandler(String id, boolean check_status) {
    Toast.makeText(
            this,
            "You changed the status for the row with an id of " + id +
                    " the status is now " + new Boolean(check_status).toString(),
            Toast.LENGTH_SHORT).show();
}
  • Ignore the error that the method doesn't override method from it's superclass. 忽略该方法不会从其超类覆盖方法的错误。

Third change the Class declaration to implement the interface by adding implements myOnCheckedChangedInterface as per :- 第三次更改Class声明以通过添加implements myOnCheckedChangedInterface来实现接口, implements myOnCheckedChangedInterface如下:

public class Lights extends AppCompatActivity implements myOnCheckedChangedInterface {

Lastly change MyCustomCursorAdapter to be able to call the myOnCheckedChangedHandler 最后更改MyCustomCursorAdapter使其能够调用myOnCheckedChangedHandler

eg 例如

public class MyCustomCursorAdapter extends CursorAdapter {
    Lights calling_activity; //<<<<<<<<<<@@@@@@@@@@@ ADDED for interface

    public MyCustomCursorAdapter(Context context, Cursor c) {
        super(context, c, 0);
        this.calling_activity = (Lights) context; //<<<<<<<<<<@@@@@@@@@@@ ADDED for interface
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        if (position % 2 == 0) {
            view.setBackgroundColor(0xFFAAAAFF);
        } else {
            view.setBackgroundColor(0xAAAAAAFF);
        }
        return view;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.adapter,parent,false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ((TextView)view.findViewById(R.id.id)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager._ID)));
        ((TextView)view.findViewById(R.id.KEYCODE)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager.TITLE)));
        ((TextView)view.findViewById(R.id.NAME)).setText(cursor.getString(cursor.getColumnIndex(DatabaseManager.DESC)));

        Switch thisswitch = view.findViewById(R.id.the_switch);
        thisswitch.setTag(cursor.getString(cursor.getColumnIndex(DatabaseManager._ID)));
        thisswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                /**
                Toast.makeText(buttonView.getContext(),
                        "You clicked the switch for ID " + (String) buttonView.getTag() +
                                " the status is now " + (new Boolean(isChecked)).toString(),
                        Toast.LENGTH_SHORT)
                        .show()
                **/
                calling_activity.myOnCheckedChangedHandler((String)buttonView.getTag(),isChecked); //<<<<<<<<<<@@@@@@@@@@@ ADDED for interface
            }
        });
    }
}
  • See commments with //<<<<<<<<<<@@@@@@@@@@@ ADDED for interface for changes 请参阅添加/// <<<<<<<<< @@@@@@@@@@@@@@@@@@的评论以获取更改界面
  • The original Toast has been commented out as it is no longer needed 原始的Toast已被注释掉,因为不再需要它
  • Note this isn't the tidiest way as the Adapter is tied to a Lights activity, it's just meant to be a simple example. 请注意,这不是最简单的方法,因为适配器与Lights活动相关,它只是一个简单的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM