I'm trying to make a simple application in Android that displays all the beacons that are found in a ListView by using the AltBeacon library. The problem that I'm having is that no beacon is shown, I keep on getting a blank screen without any beacons.
Any ideas what could be wrong with my code?
This is the code I have:
MainActivity.java:
public class MainActivity extends Activity implements BeaconConsumer, RangeNotifier {
public BeaconManager mBeaconManager;
public List<Beacon> beaconlijst;
ListView lijst;
public BeaconListAdapter listAdapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconlijst = new ArrayList<>();
lijst = (ListView)findViewById(R.id.listViews);
listAdapter = new BeaconListAdapter(this, beaconlijst);
lijst.setAdapter(listAdapter);
mBeaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
mBeaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
Region region = new Region("all-beacons-region", null, null, null);
try {
mBeaconManager.startRangingBeaconsInRegion(region);
}catch(RemoteException e) {
e.printStackTrace();
}
mBeaconManager.setRangeNotifier(this);
}
#Override
public void didRangeBeaconsInRegion(final Collection<Beacon> beacons, Region region) {
runOnUiThread(new Runnable() {
#Override
public void run() {
beaconlijst = new ArrayList<>(beacons);
listAdapter.notifyDataSetChanged();
}
});
}
public void onPause() {
super.onPause();
mBeaconManager.unbind(this);
}
}
BeaconListAdapter.java:
public class BeaconListAdapter extends BaseAdapter {
private Activity activity;
private List<Beacon> beacons;
private static LayoutInflater inflater = null;
public BeaconListAdapter(Activity _activity, List<Beacon> _beacons) {
this.activity = _activity;
this.beacons = _beacons;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return beacons.size();
}
#Override
public Object getItem(int position) {
return beacons.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(convertView == null ) {
view = inflater.inflate(R.layout.tupple_monitoring, null);
}
TextView uuid = (TextView)view.findViewById(R.id.BEACON_uuid);
TextView rssi = (TextView)view.findViewById(R.id.BEACON_rssi);
TextView txpower = (TextView)view.findViewById(R.id.BEACON_txpower);
Beacon beacon = beacons.get(position);
if(beacon != null) {
uuid.setText(beacon.getId2().toString());
rssi.setText(beacon.getRssi());
txpower.setText(beacon.getTxPower());
}
return view;
}
}
Any help would greatly be appreciated.
Related
I have an Fragment with recycleview where I populate it with json items from internet.
It load fine and Next step I want to is open new Activity when any row is clicked. It works in activity, thus I modified the same code for fragment but for fragment it throws exception in line
mExampleAdapter.setOnItemClickListener(getActivity());
with errror setOnItemClickListener of refrence adatper cannot be applied to Fragment activty and thus when I change line to
(ExampleAdapter.OnItemClickListener)
and when i build and run . Then app crashes with error that Mainactivity which holds framgnet cannot be cast in to .ExampleAdapter$OnItemClickListener
Here is my whole Fragment class
public class Mynotes extends Fragment implements ExampleAdapter.OnItemClickListener{
public static final String YTD_LINK = "link";
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
String url="https://api.myjson.com/bins/16mecx";
public Mynotes() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.activity_jsonfeed, container, false);
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.addItemDecoration(new MyDividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL, 36));
mExampleList = new ArrayList<>();
mExampleAdapter = new ExampleAdapter(getActivity(), mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
mExampleAdapter.setOnItemClickListener((ExampleAdapter.OnItemClickListener) getActivity());
parseJSON();
return view;
}
private void parseJSON() {
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
myProgressBar.setVisibility(View.GONE);
try {
JSONArray jsonArray = response.getJSONArray("hits");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String videoTitle = hit.getString("title");
String link = hit.getString("link");
mExampleList.add(new ExampleItem(videoTitle, link));
mExampleAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
#Override
public void onItemClick(int position) {
Intent intent = new Intent(getActivity(), NewActiviyt.class);
ExampleItem clickedItem = mExampleList.get(position);
intent.putExtra(YTD_LINK, clickedItem.getmLink());
startActivity(intent);
}
#Override
public void onRefresh() {
}
}
and my Adapter Class is
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private Context mContext;
private ArrayList<ExampleItem> mExampleList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public ExampleAdapter(Context context, ArrayList<ExampleItem> exampleList) {
mContext = context;
mExampleList = exampleList;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.example_item, parent, false);
return new ExampleViewHolder(v);
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
String title = currentItem.getTitle();
// int likeCount = currentItem.getLikeCount();
// String imageUrl = currentItem.getImageUrl();
holder.mTextViewCreator.setText(title);
// holder.mTextViewLikes.setText("Likes: " + likeCount);
// Glide.with(mContext).load(imageUrl).apply(RequestOptions.circleCropTransform()).into(holder.mImageView);
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView mTextViewCreator;
// public TextView mTextViewLikes;
// public ImageView mImageView;
public ExampleViewHolder(View itemView) {
super(itemView);
// mTextViewLikes = itemView.findViewById(R.id.text_view_likes);
// mImageView = itemView.findViewById(R.id.image_view);
mTextViewCreator = itemView.findViewById(R.id.text_title);
}
#Override
public void onClick(View view) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
}
}
Thanks in advance.
replace getActivity with getContext when you work in fragment,
You can read more here
What is different between getContext and getActivity from Fragment in support library?
Your activity should implement ExampleAdapter.OnItemClickListener
I'm trying to figure out how to get data from a clicked item in a RecyclerView to a listview in a Fragment. I can't seem to figure out how to do this, as I can't get my bundle to work.
I've tried various solutions offered here on Stackoverflow, but none of them have worked. I have managed to get the info from the recyclerview, but I am stuck trying to figure out how I can pass it to the fragment. Can someone please help me?
The Adapter class:
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder> {
private Context context;
ArrayList<FoodActivity> list;
public FoodAdapter(ArrayList<FoodActivity> list){
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item_food, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.foods.setText(list.get(position).getName());
holder.carbo.setText(list.get(position).getCarbohydrates());
holder.protein.setText(list.get(position).getProtein());
holder.fats.setText(list.get(position).getFats());
//Get items from recyclerview when user clicks them. Then send them to FoodFragment
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String foods = list.get(position).getName();
String carbo = list.get(position).getCarbohydrates();
String protein = list.get(position).getProtein();
String fats = list.get(position).getFats();
Toast.makeText(v.getContext(), "test: " + foods, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView foods, carbo, fats, protein;
public ViewHolder(View itemView) {
super(itemView);
carbo = itemView.findViewById(R.id.carbo);
protein = itemView.findViewById(R.id.protein);
fats = itemView.findViewById(R.id.fats);
foods = itemView.findViewById(R.id.food);
}
}
}
The Fragment where the data comes from:
public class TrackingFragment extends Fragment {
DatabaseReference databaseReference;
ArrayList<FoodActivity> list;
RecyclerView recyclerView;
SearchView searchView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tracking, container, false);
databaseReference = FirebaseDatabase.getInstance().getReference().child("foods");
recyclerView = view.findViewById(R.id.rv);
searchView = view.findViewById(R.id.searchFood);
return view;
}
#Override
public void onStart() {
super.onStart();
if(databaseReference != null){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()){
list.add(ds.getValue(FoodActivity.class));
}
FoodAdapter adapter = new FoodAdapter(list);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if(searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str){
ArrayList<FoodActivity> searchList = new ArrayList<>();
for(FoodActivity object : list){
if(object.getName().toLowerCase().contains(str.toLowerCase())){
searchList.add(object);
}
}
FoodAdapter foodAdapter = new FoodAdapter(searchList);
recyclerView.setAdapter(foodAdapter);
}
}
And the class where it needs to go:
public class FoodFragment extends Fragment {
ImageButton addFood;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_food, container, false);
addFood = view.findViewById(R.id.addFood);
addFood.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new TrackingFragment());
fr.addToBackStack(null).commit();
}
});
return view;
}
}
The most simple is to add variables you need to your activity, set their values with onClick() and then retrieve data in other fragment:
in activity:
String foods;
public String getFoods() {
return foods;
}
public void setFoods(String foods) {
this.foods = foods;
}
in adapter:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((YourActivity)getActivity()).setFoods("Any value");
}
});
in destination fragment:
String foods = ((YourActivity)getActivity()).getFoods();
Add an interface to your adapter as follow
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder> {
interface OnClickListener {
void onClick(FoodActivity clickedItem);
}
private OnClickListener mCallback;
private ArrayList<FoodActivity> list;
public FoodAdapter(ArrayList<FoodActivity> list){
this.list = list;
}
public void setOnClickListener(OnClickListener callback) {
mCallback = callback;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item_food, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.foods.setText(list.get(position).getName());
holder.carbo.setText(list.get(position).getCarbohydrates());
holder.protein.setText(list.get(position).getProtein());
holder.fats.setText(list.get(position).getFats());
//Get items from recyclerview when user clicks them. Then send them to FoodFragment
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mCallback != null)
mCallback.onClick(list.get(position));
}
});
}
#Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView foods, carbo, fats, protein;
public ViewHolder(View itemView) {
super(itemView);
carbo = itemView.findViewById(R.id.carbo);
protein = itemView.findViewById(R.id.protein);
fats = itemView.findViewById(R.id.fats);
foods = itemView.findViewById(R.id.food);
}
}
}
Android sometimes is a little complicated, when it involves the full stack:
01 RecyclerView Adapter
/** 01. Some Adapter */
public class SomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private WeakReference<Context> mContext;
/** Constructor */
public SomeAdapter(#NonNull Context context) {
this.mContext = new WeakReference<>(context);
}
#NonNull
protected Context getContext() {
return this.mContext.get();
}
/** Call to Activity from within the adapter. */
private void someMethod() {
SomeActivity activity = (SomeActivity) getContext();
synchronized(activity) {activity.showLoginDialog();}
}
}
02 AppCompatActivity
/** 02. Some Activity */
public class SomeActivity extends AppCompatActivity {
#Nullable
private BaseFragment currentFragment = null;
/** Constructor */
public SomeActivity() {}
public void setCurrentFragment(Fragment fragment) {
this.currentFragment = fragment;
}
/** Call to the current Fragment. */
public void someMethod() {
if (currentFragment != null) {
currentFragment.someMethod();
}
}
}
03 Fragment
/** Some Fragment */
public class SomeFragment extends Fragment {
/** Constructor */
public SomeFragment() {}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
((BaseActivity) context).setCurrentFragment(this);
}
#Override
public void onDetach() {
super.onDetach();
((BaseActivity) getActivity()).setCurrentFragment(this);
}
}
To get your data from FoodAdapter to TrackingFragment, you can add TrackingFragment (or an interface it implements, ideally) as a parameter to the FoodAdapter constructor, then use that instance to forward your ViewHolder clicks to TrackingFragment for handling.
To get your data from TrackingFragment to FoodFragment, use the setTargetFragment/onActivityResult pattern for fragment <-> fragment communication. This answer has an example: https://stackoverflow.com/a/13733914/3238938
I am working on a android project, here i have a class CategoryProvider which extends ContentProvider class and i also implements LoaderManager.LoaderCallbacks<Cursor> in my main Activity and I also have CategoryAdapter class which extends RecyclerView.Adapter<CategoryAdapter.ViewHolder>. I have 3 records in my Sqlite database, now after initialization of Loader in main Activity when data is loading in the adapter it loads each record twice so how to fix that.
CategotyAdapter.java
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder> {
Cursor dataCursor;
Context context;
String global_lang = "English";
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.titleText);
imageView = (ImageView) itemView.findViewById(R.id.icons);
}
}
public CategoryAdapter(Activity mContext, Cursor cursor) {
dataCursor = cursor;
context = mContext;
}
#Override
public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View cardview = LayoutInflater.from(parent.getContext())
.inflate(R.layout.option_layout, parent, false);
return new ViewHolder(cardview);
}
#Override
public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) {
dataCursor.moveToPosition(position);
String imagePath = dataCursor.getString(dataCursor.getColumnIndex(CategoryContract.CategoryEntry.COLUMN_IMAGE_PATH));
String cEn_name = dataCursor.getString(dataCursor.getColumnIndex(CategoryContract.CategoryEntry.COLUMN_CONTENT_EN));
String cHi_name = dataCursor.getString(dataCursor.getColumnIndex(CategoryContract.CategoryEntry.COLUMN_CONTENT_HI));
if(global_lang.equals("English"))
holder.name.setText(cEn_name);
else
holder.name.setText(cHi_name);
Glide.with(context)
.load(imagePath)
.apply(new RequestOptions()
.placeholder(R.drawable.loading))
.into(holder.imageView);
}
public Cursor swapCursor(Cursor cursor) {
if(dataCursor == cursor) {
return null;
}
Cursor oldCursor = dataCursor;
this.dataCursor = cursor;
if(cursor != null) {
this.notifyDataSetChanged();
}
return oldCursor;
}
#Override
public int getItemCount() {
if(dataCursor != null)
Log.d("datacursor count", " " +dataCursor.getCount());
else
Log.d("datacursor count", "datacursor is null");
return (dataCursor == null) ? 0 : dataCursor.getCount();
}
public void changeLang(String lang) {
this.global_lang = lang;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
}
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firstTimeUser();
ActivityToolbar = (Toolbar) findViewById(R.id.toolbar);
ActivitySpinner = (Spinner) findViewById(R.id.spinner);
ActivityToolbar.setTitle(R.string.app_name);
ActivityAdapter = ArrayAdapter.createFromResource(this, R.array.languages, R.layout.drop_menu);
ActivityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ActivitySpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
ActivitySpinner.setAdapter(ActivityAdapter);
listeners();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
}
categoryAdapter = new CategoryAdapter(this, null);
recyclerView.setAdapter(categoryAdapter);
getLoaderManager().initLoader(CATEGORY_LOADER, null, this);
}
public void listeners() {
ActivitySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
categoryAdapter.changeLang(ActivitySpinner.getSelectedItem().toString());
getLoaderManager().restartLoader(CATEGORY_LOADER, null, MainActivity.this);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] data = {
CategoryContract.CategoryEntry._ID,
CategoryContract.CategoryEntry.COLUMN_IMAGE_PATH,
CategoryContract.CategoryEntry.COLUMN_CONTENT_EN,
CategoryContract.CategoryEntry.COLUMN_CONTENT_HI
};
return new CursorLoader(
this,
CategoryContract.CategoryEntry.CONTENT_URI,
data,
null,
null,
null
);
}
#Override
protected void onResume() {
super.onResume();
loader_flag = 0;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
categoryAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
categoryAdapter.swapCursor(null);
}
Thanks!!
Ok, I got it after a lot of debugging. Here I am using Sync Adapter framework in my App which syncs the data at the background, when it trying to reload data the duplicate data is synced rapidly with new ID and it was rendered by recyclerView. so now I am using some constraints and changing my Database structure.
I have been working on making my RecyclerView list clickable. I have not successfully retrieve any results from clicks yet. I have searched through stackoverflow and youtube, but not understanding what I am implementing wrong. My Adapter is
Food Adapter
ublic class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private Context mCtx;
private List<Food> foodList;
public FoodAdapter(Context mCtx, List<Food> foodList) {
this.mCtx = mCtx;
this.foodList = foodList;
}
#Override
public FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.list_item, null);
FoodViewHolder foodView = new FoodViewHolder(view, mCtx, foodList);
return foodView;
}
#Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
Food food = foodList.get(position);
holder.txtFoodTitle.setText(food.getFoodTitle());
holder.txtFoodDesc.setText(food.getFoodDesc());
holder.txtFoodLoc.setText(food.getFoodLoc() + ", CA");
holder.txtFoodAuthor.setText(food.getFoodAuthor());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(food.getImage(), null));
}
#Override
public int getItemCount() {
return foodList.size();
}
class FoodViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView;
TextView txtFoodTitle, txtFoodDesc, txtFoodLoc, txtFoodAuthor;
List<Food> foods;
Context ctx;
public FoodViewHolder(View itemView, Context ctx, List<Food> foods) {
super(itemView);
itemView.setOnClickListener(this);
this.ctx = ctx;
this.foods = foods;
imageView = itemView.findViewById(R.id.foodImg);
txtFoodTitle = itemView.findViewById(R.id.foodTitle);
txtFoodDesc = itemView.findViewById(R.id.foodDesc);
txtFoodLoc = itemView.findViewById(R.id.foodLoc);
txtFoodAuthor = itemView.findViewById(R.id.foodAuthor);
}
#Override
public void onClick(View view) {
int position = getAdapterPosition();
//Food food = this.foods.get(position);
Log.i(TAG, "Clicked!");
}
}
}
FragmentList
public class FragmentList extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_fragment_list, container, false);
RecyclerView recyclerView;
final FoodAdapter adapter;
final List<Food> foodList = new ArrayList<>();
recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new FoodAdapter(getActivity(), foodList);
recyclerView.setAdapter(adapter);
String url = "url";
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i(TAG, response);
try {
JSONArray foodResp = new JSONArray(response);
for (int i = 0; i < foodResp.length(); i++) {
JSONObject foodObj = foodResp.getJSONObject(i);
foodList.add(
new Food(
foodObj.getInt("u_id"),
R.drawable.ic_launcher_background,
foodObj.getString("mealTitle"),
foodObj.getString("mealDesc"),
foodObj.getString("cityName"),
foodObj.getString("userName")
));
}
if (adapter != null) {
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.i(TAG, "Error: " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG, "err: " + error.toString());
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("data", "value");
return params;
}
};
Volley.newRequestQueue(getActivity()).add(sr);
return v;
}
One of the original videos I was watching showed it done with an ArrayList<>, but I already set up my RecyclerView with List. I do not imagine that that would matter. Any advice would be appreciated. Thanks!
Try to set Click Listener in your FragmentList.java.
Food Adapter
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private Context mCtx;
private List<Food> foodList;
public FoodAdapter(Context mCtx, List<Food> foodList) {
this.mCtx = mCtx;
this.foodList = foodList;
}
public static class FoodViewHolder extends RecyclerView.FoodViewHolder {
ImageView imageView;
TextView txtFoodTitle, txtFoodDesc, txtFoodLoc, txtFoodAuthor;
//List<Food> foods;
//Context ctx;
public FoodViewHolder(View v) {
super(v);
imageView = itemView.findViewById(R.id.foodImg);
txtFoodTitle = itemView.findViewById(R.id.foodTitle);
txtFoodDesc = itemView.findViewById(R.id.foodDesc);
txtFoodLoc = itemView.findViewById(R.id.foodLoc);
txtFoodAuthor = itemView.findViewById(R.id.foodAuthor);
}
}
#Override
public FoodAdapter.FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.list_item, parent, false);
return FoodViewHolder(view);
}
#Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
Food food = foodList.get(position);
holder.txtFoodTitle.setText(food.getFoodTitle());
holder.txtFoodDesc.setText(food.getFoodDesc());
holder.txtFoodLoc.setText(food.getFoodLoc() + ", CA");
holder.txtFoodAuthor.setText(food.getFoodAuthor());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(food.getImage(), null));
}
#Override
public int getItemCount() {
return foodList.size();
}
}
FragmentList
public class FragmentList extends Fragment {
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_fragment_list, container, false);
final FoodAdapter adapter;
final List<Food> foodList = new ArrayList<>();
recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new FoodAdapter(getActivity(), foodList);
recyclerView.setAdapter(adapter);
String url = "url";
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i(TAG, response);
try {
JSONArray foodResp = new JSONArray(response);
for (int i = 0; i < foodResp.length(); i++) {
JSONObject foodObj = foodResp.getJSONObject(i);
foodList.add(
new Food(
foodObj.getInt("u_id"),
R.drawable.ic_launcher_background,
foodObj.getString("mealTitle"),
foodObj.getString("mealDesc"),
foodObj.getString("cityName"),
foodObj.getString("userName")
));
}
if (adapter != null) {
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.i(TAG, "Error: " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG, "err: " + error.toString());
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("data", "value");
return params;
}
};
Volley.newRequestQueue(getActivity()).add(sr);
return v;
}
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/* --- Adding the Listener here --- */
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
//Food food = this.foods.get(position);
Log.i(TAG, "Clicked!");
}
}));
}
}
And this will be your RecyclerItemClickListener.java file:
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
GestureDetector mGestureDetector;
public interface OnItemClickListener{
void onItemClick(View view, int position);
}
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View childView = rv.findChildViewUnder(e.getX(),e.getY());
if(childView != null && mListener != null && mGestureDetector.onTouchEvent(e)){
mListener.onItemClick(childView, rv.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
Hope it will help :)
You need to set the click listener on the specific element.
For example if you want to do something when you click on the image then :
You need to call holder.imageview.setOnClickListener(this);
Try this !!
If you want to set the click listener to the entire row, then you might want to set the click listener on the root element of your row item.
handling clicks for the entire item "the viewholder"
1. create custom listener
public class RecyclerClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
2. listen for clicks using our listener inside your
recyclerView.addOnItemTouchListener(
//use getActivity() if you are using fragment instead of MyActivity.this
new RecyclerClickListener(MyActivity.this, recyclerView, new RecyclerClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Food food= foodList.get(position);
//do whatever
}
#Override
public void onLongItemClick(View view, int position) {
// to be implement add to favourite
}
})
);
if you are listening to a specifc item inside the view holder.
1.create an inner interface inside your adapter and create an instance of it.
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(Food item);
}
//and also the constructor
public MyAdapter(List<Food> foodList,Context ctx,OnItemClickListener
listener){
// ......
this.mListener=mListener;
}
2.inside your viewholder class create setListener() method
public void SetListener(final Food item, final OnItemClickListener listener) {
mButton.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
3.inside you onBindView
#Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
//...
viewHolder.setListener(foodList.get(position), mListener);
}
4.inside your activity or fragment
MyAdapter adapter=new MyAdapter(foodList,getActivity(),new MyAdapter.OnItemClickListener(){
#Override
public void onItemClick(Food item){
}
});
I am stuck because I don't know how to change populating listView to populate spinner.
The code below should work when in layout spinner is changed to listview, but I need spinner.
Can anyone explain to me how to do it?
In the Java file I'm using DefaultHttpClient method.
MainActivity:
public class MainActivity extends ActionBarActivity {
private Spinner spinner;
private JSONArray jsonArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.spinner=(Spinner) this.findViewById(R.id.spinner);
new GetStat().execute(new Polaczenie());
}
public void setSpinner(JSONArray jsonArray){
this.spinner.setAdapter(new GetAllTeamListViewAdapter(jsonArray,this));
//this.GetStat.setAdapter(new GetAllTeamListViewAdapter(jsonArray,this));
}
public class GetStat extends AsyncTask<Polaczenie,Long,JSONArray>
{
#Override
protected JSONArray doInBackground(Polaczenie... params)
{
return params[0].GetStat();
}
#Override
public void onPostExecute(JSONArray jsonArray)
{
setSpinner(jsonArray);
}
}
}
GetAllTeamListViewAdapter activity:
public class GetAllTeamListViewAdapter extends BaseAdapter {
private JSONArray dataArray;
private Activity activity;
private static LayoutInflater inflater = null;
public GetAllTeamListViewAdapter(JSONArray jsonArray, Activity a)
{
this.dataArray=jsonArray;
this.activity=a;
inflater=(LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.dataArray.length();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ListTeam team;
if(convertView == null)
{
convertView= inflater.inflate(R.layout.get_all_team_list_view, null);
team = new ListTeam();
team.Name=(TextView) convertView.findViewById(R.id.team_full_name);
}
else
{
team =(ListTeam) convertView.getTag();
}
try
{
JSONObject jsonObject=this.dataArray.getJSONObject(position);
team.Name.setText(jsonObject.getString("name"));
}
catch(JSONException e)
{
e.printStackTrace();
}
return convertView;
}
private class ListTeam
{
private TextView Name;
}
}