2017-09-19 3 views
1

Ich habe eine Aktivität, die aus zwei Hauptelementen besteht: einem RecyclerView und einem ListView. Der RecyclerView fungiert als Filter und das Auswählen/Entfernen von Elementen in diesem wird sich auf den Inhalt des ListView auswirken. Alles funktioniert gut, bis ich versucht habe, den onClickListener auf dem RecyclerView zu implementieren und erkannte, dass das keine Option ist.Aktivität aktualisieren, wenn Sie auf RecyclerView klicken

Ich habe versucht, den Weg der Einstellung eines OnClickListener innerhalb des ViewHolder hinunterzugehen, aber es muss eine Funktion innerhalb der Hauptaktivität aufrufen und es listView aktualisieren. Eine solche Interaktion löst den folgenden Fehler:

java.lang.NullPointerException 
    at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:117) 
    at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149) 
    at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29) 
    at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54) 
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202) 
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183) 
    at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519) 
    at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190) 
    at .newsScreen._$_findCachedViewById(newsScreen.kt) 
    at .newsScreen.filterNews(newsScreen.kt:71) 
    at Cells.NewsFeedList$NewsSource$1.onClick(News Lists.kt:84) 

Angenommen, es Sinn macht, da ich versuche UI für den Zugriff auf von außerhalb seiner Klasse, aber ich konnte nicht finden, Alternativen zu.

RecyclerView Adapter:

class NewsFeedList() : RecyclerView.Adapter<NewsFeedList.NewsSource>() { 
    private var source: List<NewsFeed> = ArrayList() 

    constructor(s: ArrayList<NewsFeed>) : this() { 
     source = s 
    } 

    class NewsSource : RecyclerView.ViewHolder { 

     private var mTextView: TextView? = null 

     constructor(v: View): super(v) { 
      mTextView = v.title 
     } 

     fun bindInfo(news: NewsFeed, view: View, int: Int) { 
      mTextView!!.text = news.title 
      view.tag = int 
      view.setOnClickListener { newsScreen().filterNews(view.tag.toString().toInt()) } 
      if (news.selected) view.background = ColorDrawable(Color.parseColor(news.color)) 
      else view.background = ColorDrawable(Color.parseColor(design.backgroundColor)) 
     } 
    } 

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): NewsFeedList.NewsSource { 
     val view = LayoutInflater.from(parent!!.context).inflate(R.layout.newsfeed_list, parent, false) 
     return NewsSource(view) 
    } 

    override fun onBindViewHolder(holder: NewsFeedList.NewsSource, position: Int) { 
     holder.bindInfo(source[position], holder.itemView, position) 
    } 

    override fun getItemCount(): Int { 
     return source.count() 
    } 

} 

in meinem newsScreen Klasse Dann muss ich den RecyclerView Adapter mit neuen Daten

fun filterNews(i: Int) { 

    newsFeed[i].selected = !newsFeed[i].selected 
    filter.adapter = NewsFeedList(newsFeed) 

} 

zugreifen Wenn ich alle Verweise entfernen filtern (RecyclerView), Alles ist in Ordnung, aber der Zweck des onClickListeners besteht darin, den Inhalt der Aktivitäten zu aktualisieren.

Gibt es eine Möglichkeit dies zu erreichen, oder sollte ich RecyclerView auf ein anderes UI-Element umstellen?

Edit: ich versucht habe, eine OnClickListener zum RecyclerView Zugabe, aber es scheint nicht ausgelöst werden. Code:

filter.adapter = NewsFeedList(newsFeed) 
filter.layoutManager = LinearLayoutManager([email protected], LinearLayoutManager.HORIZONTAL, false) 
filter.setOnClickListener { v: View? -> 
     filterNews(v!!.tag.toString().toInt()) 
} 
+0

Warum statt OnClickListener nicht verwenden OnItemClickListener? –

+0

Könnten Sie bitte meine aktualisierte Frage überprüfen? Ich bin mit Android nicht so vertraut, also könnte es auch etwas Offensichtliches sein, dass ich vermisse. –

+0

Es tut mir leid, der OnItemClickListener funktioniert mit RecycleView eigentlich nicht so gut. Ich habe Ihnen eine Antwort geschrieben, wie ich das NullPointerException-Problem lösen könnte. –

Antwort

1

Okay, hier ist eine andere Lösung, die Sie ausprobieren können:

diese Schnittstelle zu Ihrer App hinzufügen:

interface ClickListener { 
    void onItemClicked(int position); 
} 

implementieren es in Ihrem MainActivity (oder was auch immer Aktivität haben Sie die Tasten auf).

Übergeben Sie die Referenz der Schnittstelle in Ihrem Adapter-Konstruktor: ArrayList mList; ClickListener-Listener;

public MyAdapter(ArrayList<NewsFeed> mList, ClickListener listener) { 
    this.listener = listener; 
} 

@Override 
public MyAdapter.NavViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.someL, parent, false); 
    return new ViewHolder(v, listener); 

} 

public void getItemClicked(int position){ 
    mList.get(position); 
} 

schließlich in dir ViewHolder Klasse:

class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { 

    TextView textView; 
    ImageView imageView; 
    ClickListener listener; 

    ViewHolder(View itemView, ClickListener listener) { 
     super(itemView); 
     this.listener = listener; 
     textView = (TextView) itemView.findViewById(R.id.text_view); 
     imageView = (ImageView) itemView.findViewById(R.id.image_view); 
     textView.setOnClickListener(this) 
    } 

    @Override 
    void onClick(View v) { 
     listener.onItemClicked(getAdapterPosition()); 
    } 

Und schließlich in Ihrer Aktivität (die clicklistener-Schnittstelle implementiert) Sie Leere onItemClicked(int position); außer Kraft setzen müssen, innerhalb dessen Sie Ihre Aktion haben werden.

P. S .: Diese Antwort wurde mit großer Hilfe von Benutzern geschrieben: https://stackoverflow.com/users/2667883/chaynik

1

Für Ihre Adapter Klasse Sie eine ViewHolder Klasse werde mit (wahrscheinlich als innere Klasse), die die OnClickListener als solche in diesem Code implementiert:

class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { 

    TextView textView; 
    ImageView imageView; 

    ViewHolder(View itemView) { 
     super(itemView); 
     textView = (TextView) itemView.findViewById(R.id.text_view); 
     imageView = (ImageView) itemView.findViewById(R.id.image_view); 
    } 

    @Override 
    void onClick(View v) { 

    } 
} 

Ihr Adapter Unter der Annahme, ist keine innere Klasse Ihrer Aktivitätsklasse. Wenn Sie mit onClick() bereit sind, auf die Methoden/Variablen Ihrer Aktivitätsklasse zuzugreifen, MÜSSEN Sie die Referenz haben.

Die bevorzugte Art und Weise wird der Kontext Bezug über den Konstruktor Ihres Adapter, Ihre ViewHolder eine innere Klasse Ihres Adapter gegeben passieren:

class MyAdapter extends extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    Context context; 

    MyAdapter(Context context) { 
     this.context = context; 
    } 

    class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { 

     TextView textView; 
     ImageView imageView; 

     ViewHolder(View itemView) { 
      super(itemView); 
      textView = (TextView) itemView.findViewById(R.id.text_view); 
      imageView = (ImageView) itemView.findViewById(R.id.image_view); 
     } 

     @Override 
     void onClick(View v) { 
      // Here we gain access to non-private methods/variables 
      // of the Activity, which Context reference we are holding. 
      ((MyActivity) context).someMethod(); 
     } 
    } 
} 

Hope, das hilft.

+0

Das ist, was ich getan habe, um den Fehler in erster Linie zu bekommen –

+0

Okay, in diesem Fall müssen Sie mehr Code senden –

+0

Vielen Dank, wird morgen aktualisiert, wenn ich wieder zur Maschine komme –

Verwandte Themen