Android - 在从 Activity class 到适配器 class 之间传递数据

Android - pass data between from an Activity class to an Adapter class

我有 3 个 classes:LoginActivity、MapsActivity 和 MatchAdapter

前2个extends AppCompactActivity,最后一个ArrayAdapter。 当我登录时(如果正确,在 mySQLiteDB 上匹配)我曾经获取当前用户的 ID_contact 并将其传递给 MapsActivity 以这种方式意图:

在我的 LoginActivity 上:

String contact=databaseHelper.searchID_Contact(username,password);
Intent intent=new Intent(LoginActivity.this,MapsActivity.class);

            intent.putExtra("ID_CONTACT",contact);
            startActivity(intent);

在 MapsActivity 上,我可以通过以下方式轻松检索此数据:

public  String getId_contact(String conct){

    return conct;
}

 @Override
public void onMapReady(GoogleMap googleMap) {

String id_contact1=getIntent().getStringExtra("ID_CONTACT");
    String contact=getId_contact(id_contact1);
    Toast.makeText(MapsActivity.this, contact, Toast.LENGTH_LONG).show();
}

到现在一切正常,显示当前用户的id。 我的问题是将此数据(有意地我不知道如何)传递给另一个扩展 ArrayAdapter 的名为 MatchAdapter 的 class。

我在 MapsActivity 上试过这种方式:

public class MapsActivity extends AppCompatActivity implements ...{

public  String getId_contact(){

        String contact=getIntent().getStringExtra("ID_CONTACT");


        return contact;
    }

因此在 MatchAdaper 上尝试以这种方式检索:

MapsActivity mapsActivity=new MapsActivity();
String text=mapsActivity.getId_contact().toString();

但是什么都没有..我收到 NULLPOINTEREXCEPTION...有人可以帮助我吗?

您可以通过以下方式从适配器访问 activity 的方法,从适配器的构造函数或任何您想要的地方调用此方法。

((ActivityName)context).methodName();

当您创建 MapsActivity 的新实例时,它与调用 startActivity() 时获得的 Activity 实例不同。这基本上就是你有空指针异常的原因。

更重要的是,您永远不应该使用 "new" 手动创建 Activity 个实例。通常,系统会通过类似 startActivity() 的机制为您创建 Activity 个对象,这就是您获取它们的方式。

如果您的 activity 恰好是您的适配器 "hosting",Himanshu 的建议可以奏效,但这并不总是保证。更好的方法是将 ID 直接传递给 MatchAdapter,在构造函数中或作为直接 setter 函数。至少,您应该执行 "instanceof" 检查以确保您的适配器上下文确实属于 MapsActivity.

类型

这是我的 MatchAdapter `package vincenzo.futsal4you;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.MatchResult;


public class MatchAdapter extends ArrayAdapter{

    List list=new ArrayList();




    String text1=null;




    MatchAdapter matchAdapter;
    static String id_contatto3="";
    String fatto3="";
    Player player=new Player();




    public MatchAdapter(Context context, int resource) {
        super(context, resource);
    }

    public void add(Match object) {
        list.add(object);
        super.add(object);
    }

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

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

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

        View row=convertView;
        final Context context = null;
        final MatchHolder matchHolder;
        final String cc=null;



        if (row==null){


            LayoutInflater layoutInflater=(LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row=layoutInflater.inflate(R.layout.display_match_row,parent,false);
            matchHolder=new MatchHolder();

            matchHolder.id_match=(TextView)row.findViewById(R.id.id_partita);
            matchHolder.id_contact=(TextView)row.findViewById(R.id.id_contatto);
            matchHolder.nome_partita=(TextView)row.findViewById(R.id.nome_partita);
            matchHolder.citta=(TextView)row.findViewById(R.id.citta);
            matchHolder.indirizzo=(TextView)row.findViewById(R.id.indirizzo);
            matchHolder.data=(TextView)row.findViewById(R.id.data);
            matchHolder.ora=(TextView)row.findViewById(R.id.ora);
//            matchHolder.id_contact=row.findViewById()
            matchHolder.join_us = (Button) row.findViewById(R.id.join_us);


            row.setTag(matchHolder);

        }
        else {
            matchHolder=(MatchHolder)row.getTag();
        }

        final Match match=(Match)getItem(position);

//        matchHolder.id_contact.setText(mapsActivity.getId_partita().toString());
        matchHolder.id_match.setText(match.getId().toString());
        matchHolder.nome_partita.setText(match.getName().toString());
        matchHolder.citta.setText(match.getCitta().toString());
        matchHolder.indirizzo.setText(match.getIndirizzo().toString());
        matchHolder.data.setText(match.getData().toString());
        matchHolder.ora.setText(match.getOra().toString());

//        assert ((MapsActivity) context) != null;
//        ((MapsActivity) context).getId_partita();

//        final String contact=matchHolder.getId_contatto();


        Log.e("BOOOOOO", matchHolder.getId_contatto2());
        final String fatto=matchHolder.getId_contatto2();
        fatto3=matchHolder.getId_contatto2();




        matchHolder.join_us.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//
                String fatto2=matchHolder.getId_contatto2();
//                final String text3=mapsActivity.getId_partita(cc).toString();

                RelativeLayout rl = (RelativeLayout) v.getParent();
                RelativeLayout r2 = (RelativeLayout) v.getParent();
//                TextView tv = (TextView)rl.findViewById(R.id.nome_partita);
                TextView tv = (TextView) rl.findViewById(R.id.id_partita);
                TextView tv2 = (TextView) r2.findViewById(R.id.id_contatto);

                String id_partita = tv.getText().toString();
                String text2 = tv2.getText().toString();



                Toast.makeText(getContext(), id_partita, Toast.LENGTH_SHORT).show();
//                Toast.makeText(getContext(), matchHolder.setId_contatto(contact), Toast.LENGTH_SHORT).show();
                Toast.makeText(getContext(),matchHolder.getId_contatto2(),Toast.LENGTH_SHORT).show();


                player.setId_contatto(fatto3);
                player.setId_partita(id_partita);
//                databaseHelper=new DatabaseHelper(context);
//                databaseHelper.insertPlayer2(player);

                ((MapsActivity)context).getJoinPlayer(player);

                Toast pass1=Toast.makeText(getContext(), "One Row JOIN US created !", Toast.LENGTH_SHORT);
                pass1.show();


            }
        });

        return row;
    }

     static class MatchHolder{
        TextView id_match,nome_partita,citta,indirizzo,data,ora,id_contact;
        Button join_us;

        public MatchHolder(){}

        public String getId_contatto(String id_contatto) {
            return id_contatto;
        }
        public String getId_contatto2() {
            return id_contatto3;
        }

        public void setId_contatto(String id_contatto) {
            id_contatto3 = id_contatto;
        }


        public MatchHolder(String id_contatto){
            id_contatto3=id_contatto;

        }


    }
}

` 所以问题是我在静态(内部)class(MatchHolder)中声明了一个字符串(id_contatto3)。将其声明为 MatchAdapter 我以某种方式解决了它,但现在我想在 onClick 中调用另一个 class 中的方法(扩展 SQLiteOpenhelper 的 DatabaseHelper)..

我做不到 ((DatabaseHelper)context).mymethod() 所以我做了以下 "trick"...在 class MapsActivity 中我创建了一个方法( JoinPlayer) 方式:

public void JoinPlayer(Player player){
        databaseHelper.insertPlayer(player);
    }

DatabaseHelper 中的 insertPlayer(Player) 是:

public void insertPlayer(Player player){
        try{
        db=this.getWritableDatabase();
        }
        catch(Exception e){
           Log.e("ERROR","ERROR");
        }
        ContentValues contentValues=new ContentValues();
        String query="select * from player";
        Cursor cursor=db.rawQuery(query,null);
        int count=cursor.getCount();

        contentValues.put(COLUMN_ID_PLAYER,count);
        contentValues.put(COLUMN_ID_MATCH_PLAYER,player.getId_partita());
        contentValues.put(COLUMN_ID_CONTACT_PLAYER,player.getId_contatto());

        db.insert(TABLE_PLAYER, null, contentValues);
        db.close();
    } 

但是 Android 建议我添加一个空条件 (if ((MapsActivity)context)!=null) 而不是 ((MapsActivity)context).JoinPlayer(player) 但它告诉我它将永远null,这正是我得到的......我认为上下文是主要问题,但现在不知道如何解决它。有什么想法吗?

好的...找到解决方案...在 MatchAdapter 扩展 ArrayAdapter

DatabaseHelper databaseHelper=new DatabaseHelper(getContext()); ...比 OnClick 函数....

databaseHelper.myfunction();