从 ArrayAdapter 中开始 Activity

Start Activity from within ArrayAdapter

我有一个扩展 ArrayAdapter 的自定义适配器。单击 EMAIL 时,我想转到 MapActivity。如果我删除了意图部分,则会出现一个吐司,并显示所单击项目的正确位置。但是,如果我添加 startActivity 函数,应用程序会崩溃(没有吐司)。我删除了不相关的代码,例如获取距离和setters.getters。任何帮助或指示将不胜感激!

ArrayAdapter代码

import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.firebase.client.ChildEventListener;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import com.google.android.gms.maps.model.LatLng;
import com.google.firebase.auth.FirebaseAuth;

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

public class TrackAdapter extends ArrayAdapter{

    private Context c;
    //ArrayLists to save items

    public TrackAdapter(Context context, int resource)
    {
        super(context, resource);
        this.c = context;
    }

    public void add(/*items to be added*/)
    {
       //add to ArrayLists and super.add()
    }

    static class RowHolder
    {
        TextView EMAIL;
        TextView DISTANCE;
    }

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

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

    /*other setters and getters*/

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

        final int currentPosition = position;

        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.track_item, parent, false);

            holder = new RowHolder();

            holder.EMAIL = (TextView) row.findViewById(R.id.track_item_text);
            holder.DISTANCE = (TextView) row.findViewById(R.id.track_item_distance);

            holder.EMAIL.setOnClickListener(new View.OnClickListener() 
            {
                @Override
                public void onClick(View v) 
                {
                    Toast.makeText(c, "item at position " + currentPosition, Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(c, MapActivity.class);
                    c.startActivity(intent);
                }
            });

            row.setTag(holder);
        }
        else
        {
            holder = (RowHolder) row.getTag();
        }


        String EM = (String) getItem(position);
        holder.EMAIL.setText(EM);

        //calculate and display distance

        return row;

    }
}

我也试过用 c.getApplicationContext()v.getContext() 替换 c,但还是不行。

编辑-我 运行 模拟器上的应用程序,它转到 MapActivity。但是,当 运行 在通过 USB 连接的 android 设备上时,应用程序崩溃

EDIT2 - 这是崩溃报告

--------- beginning of crash
03-29 03:23:42.036 7768-7768/com.example.*******
E/AndroidRuntime: FATAL EXCEPTION: main

                                                                                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:672)
                                                                                at android.app.ContextImpl.startActivity(ContextImpl.java:659)
                                                                                at android.content.ContextWrapper.startActivity(ContextWrapper.java:331)
                                                                                at com.example.ankit.findyourfellow.TrackAdapter.onClick(TrackAdapter.java:127)
                                                                                at android.view.View.performClick(View.java:5204)
                                                                                at android.view.View$PerformClick.run(View.java:21153)
                                                                                at android.os.Handler.handleCallback(Handler.java:739)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:148)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

更新您的代码:

public Context c;

// Contractor   
public TrackAdapter(Context mcontext, int resource)
{
    super(mcontext, R.layout.track_item, resource);
    this.c= mcontext;
    this.resource = resource;
}

在 setText 标签之后或 return 之前调用 setOnClickListener。

holder.EMAIL.setText(EM);
  holder.EMAIL.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent(c.getApplicationContext(), NEXT_ACTIVITY.class);
                c.startActivity(intent);
            }
        });

在您的点击监听器中执行如下操作:

holder.EMAIL.setOnClickListener(new View.OnClickListener() 
        {
            @Override
            public void onClick(View v) 
            {
                Toast.makeText(c, "item at position " + currentPosition, Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(c, MapActivity.class);
                //if you want to send data to called activity uncomment next line
                // intent.putExtra("extra", "value"); 

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                c.startActivity(intent);
            }
        });

它应该有效:)

将以下代码添加到您的适配器中class

ClickListener mClickListener;
public void setClickListener(ClickListener clickListener) {
        this.mClickListener = clickListener;
    }

    public interface ClickListener {
        void onItemClick();
    }

现在在 Activity class 中添加此设置适配器:

mAdapter.setClickListener(new TrackAdapter.ClickListener() {

            @Override
            public void onItemClick() {
                 Intent intent = new Intent(YourActivity.this, MapActivity.class);
                 startActivity(intent);
            }
}

你的适配器的 onClick 方法 class 调用如下:

if (mClickListener != null ) {
                             mClickListener.onItemClick();
                        }

将标记 Intent.FLAG_ACTIVITY_NEW_TASK 添加到您的意图中。

开始前使用intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) MapActivity

试试这个:

 Intent intent = new Intent(c, MapActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 c.startActivity(intent);

即使可行,我也不确定 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 是否是所需的解决方案!
你在哪里实例化ArrayAdapter?您可以尝试将上下文转换为 activity 吗?
Intent intent = new Intent((Activity)c, MapActivity.class);
另外我想知道为什么 new Intent(v.getContext(), MapActivity.class); 不起作用?

更新:
我发现了问题所在...您需要从 applicationContext 以外的上下文开始 activity!

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag

看来你的Context c实际上是应用上下文...
所以这是要放入 onClick

的工作代码
Intent intent = new Intent(c, MapActivity.class); 
v.getContext().startActivity(intent);