【问题标题】:Android custom listView click - how to call an intent to another activityAndroid自定义listView点击 - 如何调用另一个活动的意图
【发布时间】:2016-02-12 00:48:39
【问题描述】:

请有人帮忙。我正在尝试创建一个具有自定义列表视图的应用程序,该列表视图具有文本视图和图像视图。列表项被过滤,单击列表项应该打开一个关联的活动。但是,当我单击一个提供消息的项目时,应用程序崩溃了,“线程以未捕获的异常退出”。这是我的代码。

main.java

package com.example.lenovo.filterapp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

    ListView lv;
    SearchView sv;

    String[] names = {"Lionel Messi","Christiano Ronaldo","Neymar JNR","Luis Suarez"};
    int[] images ={R.drawable.badge,R.drawable.bucky,R.drawable.dentala,R.drawable.house};

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

        lv = (ListView) findViewById(R.id.listView);
        sv = (SearchView) findViewById(R.id.searchView);

        //Adapter
        final Adapter adapter = new Adapter(this,getPlayers());
        lv.setAdapter(adapter);

        sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String query) {

                adapter.getFilter().filter(query);
                return false;
            }
        });

        final HashMap<String, Class> hashMap=new HashMap<String, Class>();


        hashMap.put("Lionel Messi",Lionel.class);
        hashMap.put("Christiano Ronaldo",Christiano.class);
        hashMap.put("Neymar JNR",Neymar.class);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                String openClass = (String) adapter.getItem(position);
                Intent myIntent1 = new Intent(MainActivity.this,
                        hashMap.get(openClass));
                startActivity(myIntent1);
            }

        });

    }

    private ArrayList<Player> getPlayers(){
        ArrayList<Player> players = new ArrayList<Player>();
        Player p;

        for (int i = 0;i<names.length;i++){
            p = new Player(names[i],images[i]);
            players.add(p);
        }
        return players;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Adapter.java

包 com.example.lenovo.filterapp;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by LENOVO on 2/6/2016.
 */
public class Adapter extends BaseAdapter implements Filterable{
    Context c;
    ArrayList<Player> players;
    CustomFilter filter;
    ArrayList<Player> filterList;

    public Adapter(Context c, ArrayList<Player> players) {
        this.c = c;
        this.players = players;
        this.filterList = players;
    }

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

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

    @Override
    public long getItemId(int position) {
        return players.indexOf(getItem(position));
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) c.getSystemService(c.LAYOUT_INFLATER_SERVICE);

        if(convertView == null){
            convertView= inflater.inflate(R.layout.activity_customrow,null);
        }

        TextView nameTxt = (TextView) convertView.findViewById(R.id.buckysTextView);

        ImageView img = (ImageView) convertView.findViewById(R.id.alisImageView);

        //Set data to them
        nameTxt.setText(players.get(position).getName());
        img.setImageResource(players.get(position).getImg());
        return convertView;
    }

    @Override
    public Filter getFilter() {

        if(filter == null){
            filter = new CustomFilter();
        }
        return filter;
    }

    //Inner Class
    class CustomFilter extends Filter{

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();

            if(constraint != null && constraint.length()>0){
                //Constraint to Upper
                constraint = constraint.toString().toUpperCase();

                ArrayList<Player> filters = new ArrayList<Player>();

                //get specific Items
                for (int i =0;i<filterList.size();i++){

                    if(filterList.get(i).getName().toUpperCase().contains(constraint)){
                        Player p = new Player(filterList.get(i).getName(),filterList.get(i).getImg());

                        filters.add(p);
                    }
                }
                results.count = filters.size();
                results.values = filters;
            }
            else {
                results.count = filterList.size();
                results.values = filterList;
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            players = (ArrayList<Player>) results.values;
            notifyDataSetChanged();
        }
    }
}

Player.java

包 com.example.lenovo.filterapp;

/**
 * Created by LENOVO on 2/6/2016.
 */
public class Player {

    private  String name;
    private int img;

    public Player(String name, int img) {
        this.name = name;
        this.img  = img;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImg() {
        return img;
    }

    public void setImg(int img) {
        this.img = img;
    }
}

activity_main.xml

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"

            >
            <SearchView

                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/searchView"
                android:layout_alignParentTop="true"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:queryHint="search...." />


            <ListView

                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:id="@+id/listView"
                android:layout_below="@+id/searchView"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_marginTop="0dp" />

        </LinearLayout>

清单

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.lenovo.filterapp.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.lenovo.filterapp.Lionel"
            android:label="@string/title_activity_lionel"
            android:theme="@style/AppTheme.NoActionBar" />
        <activity
            android:name="com.example.lenovo.filterapp.Christiano"
            android:label="@string/title_activity_christiano"
            android:theme="@style/AppTheme.NoActionBar" />
        <activity
            android:name="com.example.lenovo.filterapp.Neymar"
            android:label="@string/title_activity_neymar"
            android:theme="@style/AppTheme.NoActionBar"></activity>
    </application>

</manifest>

找到我崩溃的原因真的很难。可能是什么问题?提前致谢

【问题讨论】:

  • 您是否调试并检查hashMap.get(openClass) 是否返回正确的类名..?

标签: java android listview android-intent


【解决方案1】:

您需要在自定义列表视图中禁用组件的焦点。

 android:focusable="false"
 android:focusableInTouchMode="false"

一种解决方法就像我在我的应用程序中所做的那样 - 您可以尝试将 onItemClickListener 替换为 onItemTouchListener,如下所示:

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

    lv = (ListView) findViewById(R.id.listView);

//we need this to identify the gesture of the goalsRecyclerView touch
final GestureDetector mGestureDetector = new GestureDetector(MainActivity.this, new GestureDetector.SimpleOnGestureListener() {

            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
});

lv.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {

            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                LinearLayout child = (LinearLayout) rv.findChildViewUnder(e.getX(), e.getY());
                if (child != null && mGestureDetector.onTouchEvent(e))//only if clicked on an existing child and not swiping
                {
                    Intent intent = new Intent(ThisActivity.this, OtherActivity.class);
                    startActivityForResult(intent, 1);
                    return true;//transfer the touch event to the recyclerView
                }
                return false;//ignore the event
            }

            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
            }
            });
}

这适用于我使用 customListViews 的场景

【讨论】:

  • 谢谢,但 android studio 无法解析方法 addOnItemTouchListener。我能做些什么吗?
  • 此方法适用于 RecyclerView - 这是一个更好的选择,因为它处理下一个渲染项与最后一个隐藏项的重用。监听器是 RecyclerView.OnItemTouchListener。您可以尝试用 RecyclerView 替换您的 listView,它会起作用。
【解决方案2】:

在列表点击时执行此操作

String openClass = (String) lv.getItemAtPosition(position);

而不是

String openClass = (String) adapter.getItem(position);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多