I am really sorry for such an abstract question but I am loosing my mind here. HERE is my code for RecyclerView activity.
Please tell me what am I missing, because I am new to Android and I've tried for 4 days to figure the CardView out.
The error is
02-26 13:17:36.570 1138-1138/com.parse.starter E/CrashReporting﹕ ParseCrashReporting caught a NullPointerException exception for com.parse.starter. Building report.
02-26 13:17:36.580 1138-1138/com.parse.starter E/CrashReporting﹕ Handling exception for crash
java.lang.NullPointerException
at com.misha.adaptor.ContactAdapter.onBindViewHolder(ContactAdapter.java:31)
at com.misha.adaptor.ContactAdapter.onBindViewHolder(ContactAdapter.java:14)
The main Activity class
package com.parse.starter;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import com.misha.adaptor.ContactAdapter;
import com.misha.to.ContactInfo;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import java.util.ArrayList;
import java.util.List;
public class CardActivity extends Activity {
String column;
TextView name;
String result;
List<ContactInfo> resultContacts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card);
// getContacts()
List<ContactInfo> list = new ArrayList<>();
ContactInfo ci = new ContactInfo();
ci.name = "Mihail";
ci.gender = "male";
ci.email = "test#gmail.com";
ci.phone = "4152346153";
list.add(ci);
RecyclerView recList = (RecyclerView) findViewById(R.id.cardList);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
ContactAdapter adapter = new ContactAdapter(list);
recList.setAdapter(adapter);
// name = (TextView) findViewById(R.id.txtName);
// getMessage("fevK9QPFUW", "Message");
}
public void getMessage(String key, String columnName) {
this.column = columnName;
ParseQuery<ParseObject> query = ParseQuery.getQuery("Messages");
query.getInBackground(key, new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (e == null) {
name.setText(object.getString(column).toString());
} else {
result = "did not work";
}
}
});
}
public List<ContactInfo> getContacts() {
resultContacts = new ArrayList<>();
ParseQuery<ParseObject> contacts = ParseQuery.getQuery("Messages");
List<ParseQuery<ParseObject>> queries = new ArrayList<>();
queries.add(contacts);
ParseQuery<ParseObject> mainQuery = ParseQuery.or(queries);
mainQuery.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
for (ParseObject obj : results) {
String s = obj.getString("Message");
ContactInfo ci = new ContactInfo();
ci.name = s;
ci.email = "email";
ci.phone = "phone";
ci.gender = "gender";
resultContacts.add(ci);
}
}
}
});
return resultContacts;
}
#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_card, 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);
}
The Adaptor
package com.misha.adaptor;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.misha.to.ContactInfo;
import com.parse.starter.R;
import java.util.List;
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
private List<ContactInfo> contactList;
public ContactAdapter(List<ContactInfo> contactList) {
this.contactList = contactList;
}
#Override
public int getItemCount() {
return contactList.size();
}
#Override
public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) {
ContactInfo ci = contactList.get(i);
System.out.println("The ContactInfo = " + ci);
contactViewHolder.vName.setText(ci.name);
contactViewHolder.vPhone.setText(ci.phone);
contactViewHolder.vEmail.setText(ci.email);
contactViewHolder.vGender.setText(ci.gender);
}
#Override
public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.activity_card, viewGroup, false);
return new ContactViewHolder(itemView);
}
public class ContactViewHolder extends RecyclerView.ViewHolder {
protected TextView vName;
protected TextView vPhone;
protected TextView vEmail;
protected TextView vGender;
public ContactViewHolder(View v) {
super(v);
vName = (TextView) v.findViewById(R.id.txtName);
vPhone = (TextView) v.findViewById(R.id.txtPhone);
vEmail = (TextView) v.findViewById(R.id.txtEmail);
vGender = (TextView) v.findViewById(R.id.txtGender);
}
}
}
and Here are my layOuts:
activity_card.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".CardActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/cardList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
card_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="4dp"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txtName"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#color/bkg_card"
android:text="Name"
android:gravity="center_vertical"
android:textColor="#android:color/white"
android:textSize="14dp" />
<TextView
android:id="#+id/txtPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="#id/txtName"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="#id/txtPhone"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp" />
<TextView
android:id="#+id/txtGender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Gender"
android:textSize="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:layout_marginRight="150dp"
android:layout_alignBaseline="#id/txtEmail" />
</RelativeLayout>
</android.support.v7.widget.CardView>
contactViewHolder.vName is null in your example.
You need to call the constructor for ContactViewHolder in the ContactAdapter constructor.
Got it
#Override
public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.card_layout, viewGroup, false);
return new ContactViewHolder(itemView);
}
the R.layout.card_layout was set to R.layout.my_activity
Related
If I scroll this list RecycleView with the mouse wheel my items in the list look like unordered.
I do not understand , why?
An incorrect clicked item in the new activity from RecycleView
I have tried to create the separate class CrimeAdapter extends RecyclerView.Adapter<CrimeAdapter.CrimeHolder> and
class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener in the separate file, but I couldn't do it right.
Unfornuntely, I do not have enough experience for this.
I do not know how to write the correct code in the method public void onClick(View v)
Crime.java
package com.bignerdranch.android.criminalintent;
import java.util.Date;
import java.util.UUID;
public class Crime{
private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved;
private boolean mRequiresPolice;
public Crime() {
// Generate unique identifier
this(UUID.randomUUID());
}
public Crime(UUID id) {
mId = id;
mDate = new Date();
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
public boolean isSolved() {
return mSolved;
}
public void setSolved(boolean solved) {
mSolved = solved;
}
public boolean isRequiresPolice() {
return mRequiresPolice;
}
public void setRequiresPolice(boolean requiresPolice) {
mRequiresPolice = requiresPolice;
}
}
CrimeLab.java
package com.bignerdranch.android.criminalintent;
import android.content.Context;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class CrimeLab {
private static CrimeLab sCrimeLab;
private List<Crime> mCrimes;
public static CrimeLab get(Context context) {
if (sCrimeLab == null) {
sCrimeLab = new CrimeLab(context);
}
return sCrimeLab;
}
private CrimeLab(Context context){
mCrimes = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Crime crime = new Crime();
crime.setTitle("Crime #" + i);
crime.setSolved(i % 2 == 0);
if (i % 4 == 0 ) {crime.setRequiresPolice(true);}
else {crime.setRequiresPolice(false);}
mCrimes.add(crime);
}
}
public List<Crime> getCrimes() {
return mCrimes;
}
public Crime getCrime(UUID id){
for (Crime crime : mCrimes){
int rez = id.compareTo(crime.getId());
if (crime.getId().equals(id)){
return crime;
}
}
return null;
}
}
CrimeListFragment.java
package com.bignerdranch.android.criminalintent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.LayoutRes;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Date;
import java.util.List;
public class CrimeListFragment extends Fragment {
private static final int REQUEST_CRIME = 1;
private static final int NOT_REQUIRES_POLICE = 0;
private static final int REQUIRES_POLICE = 1;
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mAdapter;
private TextView mTitleTextView;
private TextView mDateTextView;
private ImageView mSolvedImageView;
private Button mButtonCallPolice;
private Crime mCrime;
private CharSequence mDateFormat;
private int layout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container,
false);
mCrimeRecyclerView = (RecyclerView) view
.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CrimeHolder(int layout, LayoutInflater inflater, ViewGroup parent ) {
super(inflater.inflate(layout, parent, false));
mTitleTextView = (TextView) itemView.findViewById(R.id.crime_title);
mDateTextView = (TextView) itemView.findViewById(R.id.crime_date);
mSolvedImageView = (ImageView) itemView.findViewById(R.id.crime_solved);
if (itemView.findViewById(R.id.call_police)!=null) {
mButtonCallPolice = (Button) itemView.findViewById(R.id.call_police);
}
itemView.setOnClickListener(this);
}
public void bind(Crime crime) {
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
mDateFormat = DateFormat.format("EEE, MMM dd, yyyy", mCrime.getDate());
mDateTextView.setText(mDateFormat);
mSolvedImageView.setVisibility(mCrime.isSolved() ? View.VISIBLE :
View.GONE);
if(mCrime.isRequiresPolice()){
mButtonCallPolice.setEnabled(true);
}
}
#Override
public void onClick(View view) {
Intent intent = CrimePagerActivity.newIntent(getActivity(),
CrimeLab.get(requireActivity()).getCrimes().get((getAdapterPosition())).getId());
startActivityForResult(intent, REQUEST_CRIME);
}
}
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes) {
mCrimes = crimes;
}
#Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
if (viewType==1) { layout = R.layout.list_item_crime_police;}
else { layout = R.layout.list_item_crime; }
return new CrimeHolder (layout, layoutInflater, parent);
}
#Override
public void onBindViewHolder(CrimeHolder holder, int position) {
Crime crime = mCrimes.get(position);
holder.bind(crime);
}
#Override
public int getItemCount() {
return mCrimes.size();
}
public int getItemViewType(int position) {
Crime crime = mCrimes.get(position);
return (crime.isRequiresPolice()) ? 1 : 0;
}
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
if (mAdapter == null) {
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.notifyDataSetChanged();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CRIME) {
// Обработка результата
}
}
public void returnResult() {
getActivity().setResult(Activity.RESULT_OK, null);
}
}
CrimePagerActivity.java
package com.bignerdranch.android.criminalintent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.List;
import java.util.UUID;
public class CrimePagerActivity extends AppCompatActivity {
private static final String EXTRA_CRIME_ID = "com.bignerdranch.android.criminalintent.crime_id";
private ViewPager mViewPager;
private List<Crime> mCrimes;
MyAdapter mAdapter;
public static Intent newIntent(Context packageContext, UUID crimeId) {
Intent intent = new Intent(packageContext, CrimePagerActivity.class);
intent.putExtra(EXTRA_CRIME_ID, crimeId);
return intent;
}
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime_pager);
UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);
mViewPager = (ViewPager) findViewById(R.id.crime_view_pager);
mCrimes = CrimeLab.get(this).getCrimes();
mAdapter = new MyAdapter(getSupportFragmentManager(),mCrimes);
mViewPager.setAdapter(mAdapter);
for (int i = 0; i < mCrimes.size(); i++) {
if (mCrimes.get(i).getId().equals(crimeId)) {
mViewPager.setCurrentItem(i);
break;
}
}
}
public static class MyAdapter extends FragmentStatePagerAdapter {
private List<Crime> mCrimesCopy;
public MyAdapter(FragmentManager fm, List<Crime> mCrimesParametr) {
//super(fm);
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mCrimesCopy = mCrimesParametr;
}
#Override
public int getCount() {
return mCrimesCopy.size();
}
#Override
public Fragment getItem(int position) {
Crime crime = mCrimesCopy.get(position);
return CrimeFragment.newInstance(crime.getId());
}
}
}
fragment_crime_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/crime_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
fragment_crime.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/crime_title_label"/>
<EditText
android:id="#+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/crime_title_hint"
android:inputType=""
android:autofillHints="" />
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/crime_details_label"/>
<Button
android:id="#+id/crime_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<CheckBox
android:id="#+id/crime_solved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/crime_solved_label"/>
</LinearLayout>
list_item_crime_police.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/crime_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="#string/crime_title"
android:textColor="#android:color/black"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="#+id/crime_solved"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/crime_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="#string/crime_date"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/crime_solved" />
<Button
android:id="#+id/call_police"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="#string/call_police"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/crime_date" />
<ImageView
android:id="#+id/crime_solved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:contentDescription="#string/todo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_solved" />
</androidx.constraintlayout.widget.ConstraintLayout>
list_item_crime.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/crime_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="#string/crime_title"
android:textColor="#android:color/black"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="#+id/crime_solved"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/crime_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="#string/crime_date"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/crime_solved" />
<ImageView
android:id="#+id/crime_solved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_solved"
android:contentDescription="#string/todo" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_crime_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/crime_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager.widget.ViewPager>
activity_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I think the items in the RecyclerView are unordered because the references for views which are present in your list_item_crime_police.xml or list_item_crime.xml layout file is declared as class members of CrimeListFragment and not inside CrimeHolder class as :
public class CrimeListFragment extends Fragment {
// your other views and variables related declarations
// these are problematic declaration that keeps on being reused
private TextView mTitleTextView;
private TextView mDateTextView;
private ImageView mSolvedImageView;
private Button mButtonCallPolice;
// your other declarations
// your other code
}
That's why, the same view instances such as mTitleTextView, mDateTextView, mSolvedImageView, mButtonCallPolice, etc. are being reused for every CrimeHolder instances causing the unordering of the items in the list. Now, in order to fix this problem, you can simply move these lines to code to CrimeHolder class as class variable which would ensures that every new CrimeHolder instance will have separate instances of above-mentioned views as :
private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// declare all of them here so there will be unique instances of these views for unique viewholder
private TextView mTitleTextView;
private TextView mDateTextView;
private ImageView mSolvedImageView;
private Button mButtonCallPolice;
public CrimeHolder(int layout, LayoutInflater inflater, ViewGroup parent ) {
View itemView = inflater.inflate(layout, parent, false));
super(itemView);
mTitleTextView = (TextView) itemView.findViewById(R.id.crime_title);
mDateTextView = (TextView) itemView.findViewById(R.id.crime_date);
mSolvedImageView = (ImageView) itemView.findViewById(R.id.crime_solved);
if (itemView.findViewById(R.id.call_police)!=null) {
mButtonCallPolice = (Button) itemView.findViewById(R.id.call_police);
}
itemView.setOnClickListener(this);
}
public void bind(Crime crime) {
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
mDateFormat = DateFormat.format("EEE, MMM dd, yyyy", mCrime.getDate());
mDateTextView.setText(mDateFormat);
mSolvedImageView.setVisibility(mCrime.isSolved() ? View.VISIBLE :
View.GONE);
if(mCrime.isRequiresPolice()){
mButtonCallPolice.setEnabled(true);
}
}
#Override
public void onClick(View view) {
Intent intent = CrimePagerActivity.newIntent(getActivity(),
CrimeLab.get(requireActivity()).getCrimes().get((getAdapterPosition())).getId());
startActivityForResult(intent, REQUEST_CRIME);
}
}
It fixed my problem and I hope it will fix yours too.
I want to make listView element clickable.
When i add gridView inside listView then i cant click on listView element..
How to make listView element clickable when gridView is inside listView?
I try to set focusable, descendantFocusability, clickable...
ProductsFragment.java
package pl.pieczolap.ui.products;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import pl.globoox.pieczolap.R;
import pl.pieczolap.API.getProducts;
import pl.pieczolap.MyGridView;
public class ProductsFragment extends Fragment {
private ProductsViewModel StampViewModel;
ArrayList<String> product_uid_shop = new ArrayList();
ArrayList<String> product_uid_product = new ArrayList();
ArrayList<String> product_name = new ArrayList();
ArrayList<String> product_info = new ArrayList();
ArrayList<String> product_stamps = new ArrayList();
ArrayList<String> product_clientStamps = new ArrayList();
MyGridView gridView_stamps;
ListView listView_products;
SharedPreferences sharedPref;
Integer clientStamps;
Integer needStamps;
ImageView imageView_loadingData;
TextView textView_winner;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
StampViewModel =
ViewModelProviders.of(this).get(ProductsViewModel.class);
View root = inflater.inflate(R.layout.fragment_products, container, false);
// LOAD GIF LOADING IMAGE
imageView_loadingData = root.findViewById(R.id.imageView_loadingData);
Glide.with(root).load(R.drawable.loadingdots).placeholder(R.drawable.loadingdots).into(imageView_loadingData);
listView_products = root.findViewById(R.id.listView_products);
sharedPref = getActivity().getApplicationContext().getSharedPreferences("pl.piecozlap", Context.MODE_PRIVATE);
Bundle arguments = this.getArguments();
String uid_shop = arguments.getString("uid_shop", "none");
// GET ALL STAMPS
Response.Listener<String> responseListenerUserComments = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
int errorCode = jsonResponse.getInt("errorCode");
// CANT CONNECT TO DATABASE
if (errorCode == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity().getApplicationContext());
builder.setMessage("Brak połączenia z bazą danych!").setNegativeButton("PONÓW", null).create().show();
}
// GET STAMP AND PRODUCT INFO
if (errorCode == 2) {
JSONArray products = jsonResponse.getJSONArray("products");
for (int i = 0; i < products.length(); i++) {
JSONObject jsonObject = products.getJSONObject(i);
product_uid_shop.add(jsonObject.getString("uid_shop"));
product_uid_product.add(jsonObject.getString("uid_product"));
product_name.add(jsonObject.getString("name"));
product_info.add(jsonObject.getString("info"));
product_stamps.add(jsonObject.getString("stamps"));
product_clientStamps.add(jsonObject.getString("clientStamps"));
}
// HIDE LOADING GIF
imageView_loadingData.setVisibility(View.INVISIBLE);
ProductsAdapter productsAdapter = new ProductsAdapter();
listView_products.setAdapter(productsAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
getProducts getStamps = new getProducts(sharedPref.getString("uid_client", "none"), uid_shop, responseListenerUserComments);
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
queue.add(getStamps);
return root;
}
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
public class ProductsAdapter extends BaseAdapter {
#Override
public int getCount() {
return product_uid_shop.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = getLayoutInflater().inflate(R.layout.customlayout_products, null);
clientStamps = Integer.valueOf(product_clientStamps.get(position));
needStamps = Integer.valueOf(product_stamps.get(position));
TextView textView_product_name = convertView.findViewById(R.id.textView_product_name);
TextView textView_product_info = convertView.findViewById(R.id.textView_product_info);
textView_product_name.setText(String.valueOf(clientStamps));
textView_product_info.setText(product_info.get(position));
// WINNER TEXTVIEW
TextView textView_winner = convertView.findViewById(R.id.textView_winner);
if (clientStamps == needStamps) {
textView_winner.setVisibility(View.VISIBLE);
} else {
textView_winner.setVisibility(View.INVISIBLE);
}
// -------------------- //
// CLICK ON SHOP //
// -------------------- //
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("TAGA", "sasdadsa");
new AlertDialog.Builder(getActivity().getApplicationContext())
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Continue with delete operation
}
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
});
gridView_stamps = convertView.findViewById(R.id.gridView_stamps);
StampsAdapter stampAdapter = new StampsAdapter();
gridView_stamps.setAdapter(stampAdapter);
gridView_stamps.setClickable(false);
return convertView;
}
}
// STAMP GRIDVIEW
// STAMP GRIDVIEW
// STAMP GRIDVIEW
// STAMP GRIDVIEW
public class StampsAdapter extends BaseAdapter {
#Override
public int getCount() {
return needStamps;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = getLayoutInflater().inflate(R.layout.customlayout_onestamp, null);
if (position < clientStamps) {
final ImageView imageView = convertView.findViewById(R.id.imgageView_onestamp);
Picasso.get().load("http://pieczolap.pl/admin/shops/999/stamp.jpg").into(imageView);
}
return convertView;
}
}
}
customlayout_products.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="50dp"
android:background="#drawable/customlayout_shops_background"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:background="#drawable/customlayout_shops_background">
<TextView
android:id="#+id/textView_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Info"
android:textSize="15dp" />
<TextView
android:id="#+id/textView_product_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView_product_name"
android:layout_margin="5dp"
android:text="Info"
android:textSize="10dp" />
</RelativeLayout>
<pl.pieczolap.MyGridView
android:id="#+id/gridView_stamps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:columnWidth="100dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="4"
android:padding="10dp"
android:stretchMode="spacingWidth"
android:verticalSpacing="10dp"
app:layout_constraintTop_toBottomOf="#id/relativeLayout"
tools:ignore="MissingConstraints" />
<TextView
android:id="#+id/textView_winner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:rotation="-6"
android:layout_margin="5dp"
android:textColor="#FF0000"
android:textStyle="bold"
android:text="Zebrano wszystkie!"
android:textSize="30dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_products.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:descendantFocusability="blocksDescendants"
android:focusable="true"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView_products"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:divider="#null"
android:focusable="true"
android:clickable="true"
android:dividerHeight="10dp"
android:padding="4dp"
android:layout_marginBottom="70dp"
app:layout_constraintTop_toBottomOf="#+id/button_addShop" />
<ImageView
android:id="#+id/imageView_loadingData"
android:layout_width="350dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
On Android, I want to users to be able to select multiple rows from a list. I read that I can use SelectionTracker with a RecyclerView to enable list-item selection.
But all the code examples are in Kotlin. Are there any examples of SelectionTracker in Java?
Here is a settings menu that allows the user to choose multiple settings. To begin the selection, the user has to long press any setting. Then they can tap any setting to choose more.
Activity
package com.locuslabs.android.sdk;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.selection.ItemDetailsLookup;
import androidx.recyclerview.selection.Selection;
import androidx.recyclerview.selection.SelectionPredicates;
import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.selection.StableIdKeyProvider;
import androidx.recyclerview.selection.StorageStrategy;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.gson.Gson;
import com.locuslabs.android.sdk.api.ConfigurationExperiments;
import com.locuslabs.android.sdk.api.MapExperiments;
import com.locuslabs.android.sdk.api.MapViewExperiments;
import com.locuslabs.android.sdk.api.PositionExperiments;
import com.locuslabs.android.sdk.api.VenueExperiments;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
public class SettingsActivity extends Activity {
private static final String TAG = "SettingsActivity";
SelectionTracker<Long> selectedSettingTracker;
private RecyclerView settingsRecyclerView;
private List<String> listOfUsableApis;
private ApiSettings mApiSettings;
private void setApiSettings(List<String> settingNamesSelected) {
for (String settingName : settingNamesSelected) {
if (settingName.equals(getResources().getString(R.string.api_setting_draw_line)))
mApiSettings.mDrawLine = true;
if (settingName.equals(getResources().getString(R.string.api_setting_search)))
mApiSettings.mLogSearch = true;
/* omitted rest of options for brevity */
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mApiSettings = new ApiSettings();
setContentView(R.layout.activity_settings);
settingsRecyclerView = findViewById(R.id.settingsRecyclerView);
settingsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
Button backButton = findViewById(R.id.settings_back_button);
Button saveButton = findViewById(R.id.settings_apply_button);
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setApiSettings(getSettingNamesSelected());
Intent intent = new Intent();
intent.putExtra("apiSettings", new Gson().toJson(mApiSettings));
setResult(RESULT_OK, intent);
finish();
}
});
listOfUsableApis = /* omitted for brevity */
final SettingsAdapter settingsAdapter = new SettingsAdapter();
settingsRecyclerView.setAdapter(settingsAdapter);
// Handle selection of settings
selectedSettingTracker = new SelectionTracker.Builder<Long>(
"selectedSettingTrackerId",
settingsRecyclerView,
new StableIdKeyProvider(settingsRecyclerView),
new SettingsDetailsLookup(),
StorageStrategy.createLongStorage()
).
withSelectionPredicate(SelectionPredicates.<Long>createSelectAnything()).
build();
}
private List<String> getSettingNamesSelected() {
Selection<Long> settingsSelection = selectedSettingTracker.getSelection();
Iterator<Long> settingSelectionIterator = settingsSelection.iterator();
List<String> settingNamesSelected = new ArrayList<>();
while (settingSelectionIterator.hasNext()) {
Long settingSelectionId = settingSelectionIterator.next();
String settingNameSelected = listOfUsableApis.get(settingSelectionId.intValue());
settingNamesSelected.add(settingNameSelected);
}
return settingNamesSelected;
}
public static class ApiSettings {
public boolean mDrawLine = false;
public boolean mWalkSimulator = false;
/* omitted most options for brevity */
public ApiSettings() {
}
}
private class SettingsAdapter extends RecyclerView.Adapter<SettingsAdapter.SettingViewHolder> {
public SettingsAdapter() {
setHasStableIds(true);
}
#NonNull
#Override
public SettingViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
TextView textView = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.setting_list_item, parent, false);
SettingViewHolder settingViewHolder = new SettingViewHolder(textView);
return settingViewHolder;
}
#Override
public void onBindViewHolder(#NonNull SettingViewHolder holder, final int position) {
holder.textView.setText(listOfUsableApis.get(position));
holder.textView.setActivated(selectedSettingTracker.isSelected((long) position));
holder.position = position;
}
#Override
public int getItemCount() {
return listOfUsableApis.size();
}
#Override
public long getItemId(int position) {
return Long.valueOf(position);
}
public class SettingViewHolder extends RecyclerView.ViewHolder {
public int position;
public TextView textView;
public SettingViewHolder(TextView v) {
super(v);
textView = v;
}
}
}
private class SettingsDetailsLookup extends ItemDetailsLookup<Long> {
#Nullable
#Override
public ItemDetails<Long> getItemDetails(#NonNull MotionEvent event) {
View view = settingsRecyclerView.findChildViewUnder(event.getX(), event.getY());
if (view != null) {
final RecyclerView.ViewHolder viewHolder = settingsRecyclerView.getChildViewHolder(view);
if (viewHolder instanceof SettingsAdapter.SettingViewHolder) {
final SettingsAdapter.SettingViewHolder settingViewHolder = (SettingsAdapter.SettingViewHolder) viewHolder;
return new ItemDetailsLookup.ItemDetails<Long>() {
#Override
public int getPosition() {
return viewHolder.getAdapterPosition();
}
#Nullable
#Override
public Long getSelectionKey() {
return Long.valueOf(settingViewHolder.position);
}
};
}
}
return null;
}
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#454545"
android:weightSum="100">
<Button
android:id="#+id/settings_back_button"
android:background="#454545"
android:drawableStart="#drawable/arrow_white"
android:drawableLeft="#drawable/arrow_white"
android:layout_gravity="start"
android:layout_width="#dimen/ll_mdu_10"
android:layout_height="#dimen/ll_mdu_10"
android:layout_weight="5"/>
<Space
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="90"
/>
<Button
android:id="#+id/settings_apply_button"
android:background="#454545"
android:drawableStart="#android:drawable/ic_menu_save"
android:drawableLeft="#android:drawable/ic_menu_save"
android:layout_gravity="end"
android:layout_width="#dimen/ll_mdu_10"
android:layout_height="#dimen/ll_mdu_10"
android:layout_weight="5"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Long-press for first setting, then tap other settings for multiple selection"
app:layout_constraintBottom_toTopOf="#+id/settingsRecyclerView"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/settingsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
</LinearLayout>
</LinearLayout>
Layout setting_list_item.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/setting_list_item_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/setting_background"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
Background drawable setting_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/holo_green_dark" android:state_activated="true" />
<item android:drawable="#android:color/white" />
</selector>
References:
https://developer.android.com/guide/topics/ui/layout/recyclerview#select This documentation is hard to read. It needs an example.
https://proandroiddev.com/a-guide-to-recyclerview-selection-3ed9f2381504 Hard to read Kotlin example
https://www.youtube.com/watch?v=jdKUm8tGogw&feature=youtu.be&list=PLWz5rJ2EKKc9Gq6FEnSXClhYkWAStbwlC&t=980 Google IO intro to this feature (but in Kotlin)
https://medium.com/#Dalvin/android-recycler-view-with-multiple-item-selections-b2af90eb5825 Another Java example!
I have small application written in android. I have tried to implement ExpandableListView into my main layout, but child data do not exists. Collapse works fine but, no data provided.
I have run debugger and see that my list have data.
Here is my code:
main layout - activity_post_details.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_post_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="hedza.com.durmitortourism.PostDetailsActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="center"
android:id="#+id/postDetailsTitleText"
android:textSize="32dp"
android:textStyle="bold"
android:textAlignment="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textSize="16dp"
android:layout_marginTop="18dp"
android:id="#+id/postDescText" />
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:id="#+id/ExplistDetails"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/postGalleryBtn"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/postLocationBtn"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
group_item - expandable_list_group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/listTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textColor="#android:color/black"
android:paddingTop="10dp"
android:paddingBottom="10dp" />
</LinearLayout>
expandable_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/expandedListItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:textColor="#000000"
android:textSize="16dp"
android:paddingBottom="10dp" />
</LinearLayout>
ExpandableListAdapter.class
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
public ExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail)
{
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
#Override
public Object getChild(int listPosition, int expandedListPosition)
{
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_list_item, null);
}
TextView expandedListTextView = (TextView) convertView
.findViewById(R.id.expandedListItem);
expandedListTextView.setText(expandedListText);
return convertView;
}
#Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent)
{
String listTitle = (String) getGroup(listPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_list_group, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
PostDetailsActivity.class
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class PostDetailsActivity extends AppCompatActivity {
SharedPreferences languageSharedPreferences;
private TextView postTitleTextView;
private TextView postDescTextView;
private ExpandableListView expandableListView;
private ExpandableListAdapter expandableListAdapter;
private List<String> detailsList;
private HashMap<String, List<String>> expandableListDetail;
private Button galleryBtn;
private Button locationBtn;
String locationJSON = null;
String title = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_details);
// setting icon in the action bar
getSupportActionBar().setDisplayShowTitleEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.mipmap.ic_launcher);
// get postID from post activity bundle
Intent intent = getIntent();
String postID = intent.getStringExtra("postID");
// getting language from shared preferences
languageSharedPreferences = getSharedPreferences("LanguagePreferences",
Context.MODE_PRIVATE);
String language = languageSharedPreferences.getString("lang", "me");
final ArrayList<String> viewPagerImages = new ArrayList<>();
// expandable list details initialization
detailsList = new ArrayList<String>();
expandableListDetail = new HashMap<String, List<String>>();
// initialize elements
postTitleTextView = (TextView) findViewById(R.id.postDetailsTitleText);
postDescTextView = (TextView) findViewById(R.id.postDescText);
expandableListView = (ExpandableListView) findViewById(R.id.ExplistDetails);
galleryBtn = (Button) findViewById(R.id.postGalleryBtn);
locationBtn = (Button) findViewById(R.id.postLocationBtn);
// get data from DB by post id
final PostSQLiteManager postObject = new PostSQLiteManager(getApplicationContext());
postObject.openConnection();
JSONObject posts = postObject.getPostsById(postID);
postObject.close();
try
{
JSONArray array = posts.getJSONArray("DATA");
JSONObject arrayObject = array.getJSONObject(0);
String[] images = arrayObject.getString("IMAGES").split(",");
for(int i = 0; i < images.length; i++){
viewPagerImages.add(images[i]);
}
title = arrayObject.getString("TITLE");
// set properties values
postTitleTextView.setText(arrayObject.getString("TITLE"));
postDescTextView.setText(arrayObject.getString("DESC"));
String postWebsite = arrayObject.getString("WEBSITE");
String postEmail = arrayObject.getString("EMAIL");
String postTelephone = arrayObject.getString("TELEPHONE");
locationJSON = arrayObject.getString("LOCATION");
// handling languages
if(language.contentEquals("me"))
{
detailsList.add("Web Stranica: "+postWebsite);
detailsList.add("Telefon: "+postTelephone);
detailsList.add("E-pošta: "+postEmail);
expandableListDetail.put("Detalji", detailsList);
galleryBtn.setText(R.string.galleryPostME);
locationBtn.setText(R.string.locationPostME);
}
else
{
detailsList.add("Website: "+postWebsite);
detailsList.add("Telephone: "+postTelephone);
detailsList.add("E-mail: "+postEmail);
expandableListDetail.put("Details", detailsList);
galleryBtn.setText(R.string.galleryPostEN);
locationBtn.setText(R.string.locationPostEN);
}
final List<String> listTitles = new ArrayList<>(expandableListDetail.keySet());
// generate list
expandableListAdapter = new ExpandableListAdapter(this, listTitles,
expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
// click on gallery button
galleryBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!viewPagerImages.isEmpty()){
Intent galleryIntent = new Intent(getApplicationContext(), GalleryActivity.class);
galleryIntent.putStringArrayListExtra("images", viewPagerImages);
startActivity(galleryIntent);
}else{
Toast.makeText(getApplicationContext(), "Nema slika", Toast.LENGTH_SHORT)
.show();
}
}
});
// click on location button
locationBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent locationIntent = new Intent(getApplicationContext(), MapActivity.class);
locationIntent.putExtra("location", locationJSON);
locationIntent.putExtra("title", title);
startActivity(locationIntent);
}
});
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
listTitles.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
}
catch(JSONException exception) {
exception.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
super.onCreateOptionsMenu(menu);
languageSharedPreferences = getSharedPreferences("LanguagePreferences",
Context.MODE_PRIVATE);
String language = languageSharedPreferences.getString("lang", "me");
// generate menu and its items
MenuInflater myMenu = getMenuInflater();
myMenu.inflate(R.menu.menu_layout, menu);
// change menu items depending on selected language
switch(language)
{
case "me":
menu.findItem(R.id.languageID).setTitle(R.string.languageME);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutME);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorME);
break;
case "en":
menu.findItem(R.id.languageID).setTitle(R.string.languageEN);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutEN);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorEN);
break;
default:
menu.findItem(R.id.languageID).setTitle(R.string.languageME);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutME);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorME);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.languageID:
Intent languageIntent = new Intent(getApplicationContext(), LanguageActivity.class);
startActivity(languageIntent);
return true;
case R.id.aboutID:
Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(aboutIntent);
return true;
case R.id.sponsorID:
Intent sponsorIntent = new Intent(getApplicationContext(), SponsorActivity.class);
startActivity(sponsorIntent);
default:
return true;
}
}
}
Does anyone have an idea what's wrong here?
Thank you in advance.
See this site: http://www.androidbegin.com/tutorial/android-search-filter-listview-images-and-texts-tutorial/
How do I set it to open into different activity/intent.
MainActivity.java
package com.androidbegin.filterlistviewimg;
import java.util.ArrayList;
import java.util.Locale;
import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends Activity {
// Declare Variables
ListView list;
ListViewAdapter adapter;
EditText editsearch;
String[] rank;
String[] country;
String[] population;
int[] flag;
ArrayList<WorldPopulation> arraylist = new ArrayList<WorldPopulation>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_main);
// Generate sample data
rank = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
country = new String[] { "China", "India", "United States",
"Indonesia", "Brazil", "Pakistan", "Nigeria", "Bangladesh",
"Russia", "Japan" };
population = new String[] { "1,354,040,000", "1,210,193,422",
"315,761,000", "237,641,326", "193,946,886", "182,912,000",
"170,901,000", "152,518,015", "143,369,806", "127,360,000" };
flag = new int[] { R.drawable.china, R.drawable.india,
R.drawable.unitedstates, R.drawable.indonesia,
R.drawable.brazil, R.drawable.pakistan, R.drawable.nigeria,
R.drawable.bangladesh, R.drawable.russia, R.drawable.japan };
// Locate the ListView in listview_main.xml
list = (ListView) findViewById(R.id.listview);
for (int i = 0; i < rank.length; i++)
{
WorldPopulation wp = new WorldPopulation(rank[i], country[i],
population[i], flag[i]);
// Binds all strings into an array
arraylist.add(wp);
}
// Pass results to ListViewAdapter Class
adapter = new ListViewAdapter(this, arraylist);
// Binds the Adapter to the ListView
list.setAdapter(adapter);
// Locate the EditText in listview_main.xml
editsearch = (EditText) findViewById(R.id.search);
// Capture Text in EditText
editsearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
}
}
WorldPopulation.java
package com.androidbegin.filterlistviewimg;
public class WorldPopulation {
private String rank;
private String country;
private String population;
private int flag;
public WorldPopulation(String rank, String country, String population,
int flag) {
this.rank = rank;
this.country = country;
this.population = population;
this.flag = flag;
}
public String getRank() {
return this.rank;
}
public String getCountry() {
return this.country;
}
public String getPopulation() {
return this.population;
}
public int getFlag() {
return this.flag;
}
}
listview_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:id="#+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/search" />
</RelativeLayout>
ListViewAdapter.java
package com.androidbegin.filterlistviewimg;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<WorldPopulation> worldpopulationlist = null;
private ArrayList<WorldPopulation> arraylist;
public ListViewAdapter(Context context,
List<WorldPopulation> worldpopulationlist) {
mContext = context;
this.worldpopulationlist = worldpopulationlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<WorldPopulation>();
this.arraylist.addAll(worldpopulationlist);
}
public class ViewHolder {
TextView rank;
TextView country;
TextView population;
ImageView flag;
}
#Override
public int getCount() {
return worldpopulationlist.size();
}
#Override
public WorldPopulation getItem(int position) {
return worldpopulationlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.rank = (TextView) view.findViewById(R.id.rank);
holder.country = (TextView) view.findViewById(R.id.country);
holder.population = (TextView) view.findViewById(R.id.population);
// Locate the ImageView in listview_item.xml
holder.flag = (ImageView) view.findViewById(R.id.flag);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.rank.setText(worldpopulationlist.get(position).getRank());
holder.country.setText(worldpopulationlist.get(position).getCountry());
holder.population.setText(worldpopulationlist.get(position)
.getPopulation());
// Set the results into ImageView
holder.flag.setImageResource(worldpopulationlist.get(position)
.getFlag());
// Listen for ListView Item Click
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// Send single item click data to SingleItemView Class
Intent intent = new Intent(mContext, SingleItemView.class);
// Pass all data rank
intent.putExtra("rank",
(worldpopulationlist.get(position).getRank()));
// Pass all data country
intent.putExtra("country",
(worldpopulationlist.get(position).getCountry()));
// Pass all data population
intent.putExtra("population",
(worldpopulationlist.get(position).getPopulation()));
// Pass all data flag
intent.putExtra("flag",
(worldpopulationlist.get(position).getFlag()));
// Start SingleItemView Class
mContext.startActivity(intent);
}
});
return view;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
worldpopulationlist.clear();
if (charText.length() == 0) {
worldpopulationlist.addAll(arraylist);
} else {
for (WorldPopulation wp : arraylist) {
if (wp.getCountry().toLowerCase(Locale.getDefault())
.contains(charText)) {
worldpopulationlist.add(wp);
}
}
}
notifyDataSetChanged();
}
}
listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/ranklabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ranklabel" />
<TextView
android:id="#+id/rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/ranklabel" />
<TextView
android:id="#+id/countrylabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ranklabel"
android:text="#string/countrylabel" />
<TextView
android:id="#+id/country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/rank"
android:layout_toRightOf="#+id/countrylabel" />
<TextView
android:id="#+id/populationlabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/countrylabel"
android:text="#string/populationlabel" />
<TextView
android:id="#+id/population"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/country"
android:layout_toRightOf="#+id/populationlabel" />
<ImageView
android:id="#+id/flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#000000"
android:padding="1dp" />
</RelativeLayout>
SingleItemView.java
package com.androidbegin.filterlistviewimg;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class SingleItemView extends Activity {
// Declare Variables
TextView txtrank;
TextView txtcountry;
TextView txtpopulation;
ImageView imgflag;
String rank;
String country;
String population;
int flag;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitemview);
// Get the intent from ListViewAdapter
Intent i = getIntent();
// Get the results of rank
rank = i.getStringExtra("rank");
// Get the results of country
country = i.getStringExtra("country");
// Get the results of population
population = i.getStringExtra("population");
// Get the results of flag
flag = i.getIntExtra("flag", flag);
// Locate the TextViews in singleitemview.xml
txtrank = (TextView) findViewById(R.id.rank);
txtcountry = (TextView) findViewById(R.id.country);
txtpopulation = (TextView) findViewById(R.id.population);
// Locate the ImageView in singleitemview.xml
imgflag = (ImageView) findViewById(R.id.flag);
// Load the results into the TextViews
txtrank.setText(rank);
txtcountry.setText(country);
txtpopulation.setText(population);
// Load the image into the ImageView
imgflag.setImageResource(flag);
}
}
singleitemview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/ranklabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ranklabel" />
<TextView
android:id="#+id/rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/ranklabel" />
<TextView
android:id="#+id/countrylabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ranklabel"
android:text="#string/countrylabel" />
<TextView
android:id="#+id/country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/rank"
android:layout_toRightOf="#+id/countrylabel" />
<TextView
android:id="#+id/populationlabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/countrylabel"
android:text="#string/populationlabel" />
<TextView
android:id="#+id/population"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/country"
android:layout_toRightOf="#+id/populationlabel" />
<ImageView
android:id="#+id/flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#000000"
android:padding="1dp" />
</RelativeLayout>