简体   繁体   中英

Passing Context To Custom Adapter For ListView

I have a class called Contacts, which accepts data from another activity and creates a custom ListView. My dilemma is with my CustomAdapter class. I try to pass my Activity context to my CustomAdapter's constructor. I tried, using this, Contacts.this and none are working. All of my widgets do not update with the appropriate text. So my Custom ListView will load, but there's nothing there. Instead I passed getApplicationContext(). This worked but I had to set Flags in my Custom Adapter Class and I'm not sure if it's best programming practice. First, Here is my Contacts Activity File

public class Contacts extends AppCompatActivity implements View.OnClickListener {
private Button addContactBtn;
private ListView contactList;
private CustomAdapter customAdapter;
private ArrayList<String> names = new ArrayList<>();
private ArrayList<String> phoneNums = new ArrayList<>();
private ArrayList<String> emails = new ArrayList<>();
static final int REQUEST_CODE = 1;



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

    addContactBtn = (Button)findViewById(R.id.contactAddButton);
    contactList = (ListView)findViewById(R.id.contactList);

    addContactBtn.setOnClickListener(this);

    customAdapter = new CustomAdapter(getApplicationContext(),names,phoneNums,emails);
    contactList.setAdapter(customAdapter);
}


@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.contactAddButton:{
            Intent i = new Intent(Contacts.this, AddContact.class);
            startActivityForResult(i,REQUEST_CODE);

        }

    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == REQUEST_CODE){
        if(resultCode == RESULT_OK){
            String name = data.getStringExtra("name");
            String phone = data.getStringExtra("phone");
            String email = data.getStringExtra("email");
            phoneNums.add(phone);
            names.add(name);
            emails.add(email);
        }
    }
}

}

Next, here is my CustomAdapter class. I pass my Context in here and it's where I'm having the issue. I set an onClick to certain widgets. I would like them to start ANOTHER INTENT when clicked, specifically, open up android's dial screen. Everything sets up well but when I click the widget in the CustomList View, the app crashes. I can fix this by setting flags but I'd rather solve the Context Issue. Why is the Context that I'm passing causing this issue? How Can I fix it?

public CustomAdapter(Context c,ArrayList<String>n, ArrayList<String>nums, ArrayList<String>e){

    context = c;
    phoneNumbers = nums;
    names = n;
    emails = e;
    inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

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

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

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

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

    if (view == null){
        view = inflater.inflate(R.layout.contacts_custom_row,null);
        TextView name = (TextView)view.findViewById(R.id.customRowContactName);
        TextView phone = (TextView)view.findViewById(R.id.customRowContactNumber);
        TextView email = (TextView)view.findViewById(R.id.customRowContactEmail);

        name.setText(names.get(position));
        phone.setText(phoneNumbers.get(position));
        email.setText(emails.get(position));

        phone.setOnClickListener(this);
    }
    return view;
}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.customRowContactNumber:{
            Intent i = new Intent(Intent.ACTION_DIAL);
            context.startActivity(i);//THIS IS THE ISSUE I THINK
            break;
        }
    }

}

This is the Log Cat Error:

09-22 10:38:25.679    2794-2794/com.markfeldman.mydoggydays E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.markfeldman.mydoggydays, PID: 2794
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
        at android.app.ContextImpl.startActivity(ContextImpl.java:1238)
        at android.app.ContextImpl.startActivity(ContextImpl.java:1225)
        at android.content.ContextWrapper.startActivity(ContextWrapper.java:323)
        at com.markfeldman.mydoggydays.CustomAdapter.onClick(CustomAdapter.java:73)
        at android.view.View.performClick(View.java:4780)
        at android.view.View$PerformClick.run(View.java:19866)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

You're calling another activity by using Context , so it thinks that you're trying to call outside the activity, so that you'll need to use the flag FLAG_ACTIVITY_NEW_TASK . Instead you can try pass the Activity . Like the following:

public CustomAdapter(Contacts activity,ArrayList<String>n, ArrayList<String>nums, ArrayList<String>e){

    mActivity = activity;
    phoneNumbers = nums;
    names = n;
    emails = e;
    inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.customRowContactNumber:{
            Intent i = new Intent(Intent.ACTION_DIAL);
            mActivity.startActivity(i);//THIS IS THE ISSUE I THINK
            break;
        }
    }

}

Then you're able to call just like:

customAdapter = new CustomAdapter(Contacts.this,names,phoneNums,emails);
contactList.setAdapter(customAdapter);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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