I want to add a button for each item in the Firebase recycler view.
I've created the button, it's being showed, and i'm receiving the Toast when I press it.
But - How can I get the relevant item on it's list ?
For example - When I press the 'DELETE' I want to delete that certain mission 'aspodm'. (Sorry for the large picture, how do I make it smaller?)
This is how the database looks like (vfPvsk... is the user id, and 773f... is random uuid for mission id):
And that is the code of the relevant fragment. (The Toast when clicking the button is activated - I just don't know how to get to the relevant mission in order to delete it)
package com.airpal.yonatan.airpal;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
/**
* A simple {#link Fragment} subclass.
*/
public class PendingFragment_User extends Fragment {
private String TAG = "dDEBUG";
private RecyclerView mPendingList;
private DatabaseReference mMissionsDb;
private FirebaseAuth mAuth;
private String mCurrent_user_id;
private View mMainView;
Query queries;
public PendingFragment_User() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_pending_user, container, false);
mPendingList = (RecyclerView)mMainView.findViewById(R.id.pending_recycler_user);
mAuth = FirebaseAuth.getInstance();
mCurrent_user_id = mAuth.getCurrentUser().getUid();
mMissionsDb = FirebaseDatabase.getInstance().getReference().child("Missions").child(mCurrent_user_id);
queries = mMissionsDb.orderByChild("status").equalTo("Available");
mMissionsDb.keepSynced(true);
mPendingList.setHasFixedSize(true);
mPendingList.setLayoutManager(new LinearLayoutManager(getContext()));
// Inflate the layout for this fragment
return mMainView;
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder> firebaseMissionsUserRecyclerAdapter = new FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder>(
Mission.class,
R.layout.missions_single_layout,
PendingFragment_User.MissionsViewHolder.class,
queries
) {
#Override
protected void populateViewHolder(PendingFragment_User.MissionsViewHolder missionViewHolder, final Mission missionModel, int missionPosition) {
// Log.d(TAG, "inside populateViewHolder" + missionModel.getType() + " , " + missionModel.getDescription());
missionViewHolder.setMissionName(missionModel.getType());
missionViewHolder.setMissionDescription(missionModel.getDescription());
missionViewHolder.setMissionStatus(missionModel.getStatus());
missionViewHolder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(view.getContext(), "esto es un boton"+ view.getNextFocusUpId(), Toast.LENGTH_SHORT).show();
Log.d(TAG,"The button was pressed");
}
});
}
};
mPendingList.setAdapter(firebaseMissionsUserRecyclerAdapter);
}
public static class MissionsViewHolder extends RecyclerView.ViewHolder {
View mView;
Button button ;
public MissionsViewHolder(View itemView) {
super(itemView);
mView = itemView;
button = (Button)mView.findViewById(R.id.pending_single_button);
}
public void setMissionName(String name){
TextView mMissionNameView = mView.findViewById(R.id.mission_single_name);
mMissionNameView.setText(name);
}
public void setMissionStatus(String status){
TextView mMissionStatusView = mView.findViewById(R.id.mission_single_status);
mMissionStatusView.setText(status);
if (status.equals("Available")){
mMissionStatusView.setTextColor(Color.parseColor("#008000"));;
} else {
mMissionStatusView.setTextColor(Color.parseColor("#FF0000"));;
}
}
public void setMissionDescription(String description){
TextView mMissionDescriptionView = mView.findViewById(R.id.mission_single_description);
mMissionDescriptionView.setText(description);
}
}
}
Try using a subclass rather than anonymous one. Then, you'll be able to access the getItem(int position) method of the adapter. Something along the lines of:
private class MissionAdapter extends FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder> {
public MissionAdapter(Query queries){
super(Mission.class, R.layout.missions_single_layout, PendingFragment_User.MissionsViewHolder.class, queries);
}
#Override
protected void populateViewHolder(PendingFragment_User.MissionsViewHolder missionViewHolder, final Mission missionModel, final int missionPosition) {
Log.d(TAG, "inside populateViewHolder" + missionModel.getType() + " , " + missionModel.getDescription());
missionViewHolder.setMissionName(missionModel.getType());
missionViewHolder.setMissionDescription(missionModel.getDescription());
missionViewHolder.setMissionStatus(missionModel.getStatus());
missionViewHolder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Mission clickedMission = MissionAdapter.this.getItem(missionPosition);
if (clickedMission != null){ // for the sake of being extra-safe
Log.d(TAG,"The button was pressed for mission: " + clickedMission.getType());
}
}
});
}
}
I made it print a log, but you should be able to do anything you want with the retrieved Mission object in there.
Related
I have an Activity with a RecyclerView which display Livedata from a room database.
My aim is to start a new Activity with more data from the room database when the user is clicking on the corresponding item in the RecyclerView.
For that I overwrote the onClick() method in the adapter of the RecylcerView. Each object of the RecyclerView has a Id, I need that Id to get the corresponding data from the database. So I passed the Id from the Adapter to the Activity.
To search an element by Id in the database that I need the ViewModel object in the MainAcitivty. It is initialized in the onCreate() of the Activity. The method I called in the Adapter is outside the onCreate() and I get a null object reference exception when I try to use it.
How can I use the ViewModel outside of the onCreate() method of the Activity? Or is there another way to search for the element in the database?
Thank you!
The Adapter class:
In the onClick() method is the relevant part.
package com.example.fillmyplate.activities;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder> {
private static final String TAG = "RecipeAdapter";
private List<Recipe> mRecipes = new ArrayList<>();
private LayoutInflater mInflater;
private Context mContext;
private MainActivity mainActivity = new MainActivity();
private static int backGroundIndex = 0;
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView recipeTitleItemView;
ImageView imageView;
public RecipeViewHolder(View itemView) {
super(itemView);
recipeTitleItemView = itemView.findViewById(R.id.name);
imageView = itemView.findViewById(R.id.card_image_view);
Log.d(TAG, "RecipeViewHolder: index " + backGroundIndex);
if (backGroundIndex == 0) {
imageView.setImageResource(R.drawable.background_green);
backGroundIndex++;
} else if (backGroundIndex == 1 ) {
imageView.setImageResource(R.drawable.background_red);
backGroundIndex++;
} else if (backGroundIndex == 2 ) {
imageView.setImageResource(R.drawable.background_blue);
backGroundIndex = 0;
}
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
// This should be the mistake.
mainActivity.startKnownRecipeActivity(position);
}
}
public RecipeAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.mContext = context;
}
#NonNull
#Override
public RecipeAdapter.RecipeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// Inflate an item view
View mRecipeTitleView = mInflater.inflate(
R.layout.recipe_list_row, parent, false);
return new RecipeViewHolder(mRecipeTitleView);
}
// Get data into the corrsponding views
#Override
public void onBindViewHolder(RecipeAdapter.RecipeViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: " + position);
Recipe currentRecipe = mRecipes.get(position);
Log.d(TAG, "onBindViewHolder: setText " + currentRecipe);
holder.recipeTitleItemView.setText(currentRecipe.getTitle());
}
#Override
public int getItemCount() {
return mRecipes.size();
}
public void setRecipes(List<Recipe> recipes) {
this.mRecipes = recipes;
Log.d(TAG, "setRecipes: notifydataChanged" );
notifyDataSetChanged();
}
}
MainActivity:
package com.example.fillmyplate.activities;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.cardview.widget.CardView;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainAcitivity";
private static final int NEW_RECIPE_ACTIVITY_REQUEST_CODE = 1;
private RecyclerView mRecyclerView;
private RecipeViewModel mRecipeViewmodel;
private RecyclerView.LayoutManager layoutManager;
//private final List<String> mTitleList = new LinkedList<>();
//NEU for adapter
private List<String> recipeDataList = new ArrayList<>();
RecipeRoomDatabase db;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// RECYCLER VIEW STUFF
mRecyclerView = findViewById(R.id.recycler_view1);
mRecyclerView.setHasFixedSize(true);
// user linerar layout manager
layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
// specify an adapter
final RecipeAdapter recipeAdapter = new RecipeAdapter(this);
//mAdapter = new RecipeAdapter(this, mTitleList);
mRecyclerView.setAdapter(recipeAdapter);
mRecipeViewmodel = ViewModelProviders.of(this).get(RecipeViewModel.class);
mRecipeViewmodel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
#Override
public void onChanged(List<Recipe> recipes) {
Log.d(TAG, "onChanged: " + recipes.toString());
for (Recipe rec : recipes) {
Log.d(TAG, "onChanged: " + rec.getTitle());
Log.d(TAG, "onChanged: recipe id " + rec.getUid());
}
recipeAdapter.setRecipes(recipes);
}
});
// DB
db = Room.databaseBuilder(getApplicationContext(), RecipeRoomDatabase.class, "appdb").build();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddRecipeActivity.class);
startActivityForResult(intent, NEW_RECIPE_ACTIVITY_REQUEST_CODE);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: ");
if (requestCode == NEW_RECIPE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: " + data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
// mTitleList.add(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
Recipe rec = new Recipe(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
mRecipeViewmodel.insert(rec);
} else {
Toast.makeText(
getApplicationContext(),
"saved",
Toast.LENGTH_LONG).show();
}
}
public void startKnownRecipeActivity(int position) {
Log.d(TAG, "startKnownRecipeActivity: Position " + position);
LiveData<List<Recipe>> recipe = mRecipeViewmodel.findById(position);
if (recipe.getValue().size() > 1) {
Log.d(TAG, "startKnownRecipeActivity: Error database found more than one recipe.");
} else {
Log.d(TAG, "startKnownRecipeActivity: Start activity with recipe " + recipe.getValue().get(0).getTitle());
}
}
}
The thing you need to do is to use a call back to send position back to activity.
To make sure that view position is correct you need to override 3 functions in RecyclerView Adapter:
#Override
public int getItemCount() {
return filteredUsers.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
For the Callback just create an Interface:
public interface AdapterListener {
void onClick(int id);
void onClick(ViewModel object);
}
Make a method in your Recycler Adapter:
private AdapterListener adapterListener;
public void setAdapterListener(AdapterListener mCallback) {
this.adapterListener = mCallback;
}
Implement this Interface on your Activity then you will get both methods of the interface.
public class MainActivity extends AppCompatActivity implements AdapterListener{
Register the listener by calling the setAdapterListener method in your activity after the initialization of the RecyclerView
adapterObject.setAdapterListener(MainActivity.this);
Then the last thing you need to do is call interface method in your item onClickListener, where u can either pass the complete model or just the id of the model
adapterListener.onClick(modelObject.getId());
OR
adapterListener.onClick(modelObject);
I want to add intent in sliding view pager. As I click different pages of the sliding view pager, a different activity must be called but I can't find the solution.
I have added image text and description in the view pager and a button is there in the layout
I think this would involve the use of page selected but earlier when I used onpageselected by using the position it opens up the page even if we are not clicking but I want to use intent here.
Adapterclass
package com.android.msahakyan.expandablenavigationdrawer.adapter;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.msahakyan.expandablenavigationdrawer.R;
import com.android.msahakyan.expandablenavigationdrawer.fragment.CardAdapter;
import com.android.msahakyan.expandablenavigationdrawer.fragment.CardItemString;
import java.util.ArrayList;
import java.util.List;
/**
* Created by tanis on 21-06-2018.
*/
public class CardPagerAdapterS extends PagerAdapter implements CardAdapter {
private List<CardView> mViews;
private List<CardItemString> mData;
private float mBaseElevation;
public CardPagerAdapterS() {
mData = new ArrayList<>();
mViews = new ArrayList<>();
}
public void addCardItemS(CardItemString item) {
mViews.add(null);
mData.add(item);
}
public float getBaseElevation() {
return mBaseElevation;
}
#Override
public CardView getCardViewAt(int position) {
return mViews.get(position);
}
#Override
public int getCount() {
return mData.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext())
.inflate(R.layout.adapter, container, false);
container.addView(view);
bind(mData.get(position), view);
CardView cardView = (CardView) view.findViewById(R.id.cardView);
if (mBaseElevation == 0) {
mBaseElevation = cardView.getCardElevation();
}
cardView.setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR);
mViews.set(position, cardView);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
mViews.set(position, null);
}
private void bind(CardItemString item, View view) {
TextView titleTextView = (TextView) view.findViewById(R.id.titleTextView);
TextView contentTextView = (TextView) view.findViewById( R.id.contentTextView);
ImageView imageView=(ImageView) view.findViewById( R.id.image12 ) ;
titleTextView.setText(item.getTitle());
contentTextView.setText(item.getText());
imageView.setImageResource( item.getImages() );
}
}
FragmentAction
package com.android.msahakyan.expandablenavigationdrawer.fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
//import android.support.v7.widget.LinearLayoutManager;
//import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.msahakyan.expandablenavigationdrawer.R;
import com.android.msahakyan.expandablenavigationdrawer.Registration;
import com.android.msahakyan.expandablenavigationdrawer.adapter.CardPagerAdapterS;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import in.goodiebag.carouselpicker.CarouselPicker;
import technolifestyle.com.imageslider.FlipperLayout;
import technolifestyle.com.imageslider.FlipperView;
/**
* A simple {#link Fragment} subclass.
* Use the {#link FragmentAction#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentAction extends Fragment {
ViewPager mViewPager;
CardPagerAdapterS mCardAdapter;
ShadowTransformer mCardShadowTransformer;
private Context context;
ViewPager viewPager;
String titlesText [] = {" Website Design", " Digital Marketing", " Domain Registration", "Graphics Design", " Mobile Apps", " Server Hosting",
" Software Development", " Content Marketing", " Security (SSl)"};
String detailsArray [] = {
"Your website is your digital home. We create, design, redesign, develop, improvise, and implement. We make beautiful websites",
"We help your business reach potential customers on every possible digital device through all possible media channels ",
"To launch your website the first thing you need is the domain name. You can choose your domain name with us here ",
"We generate creative solutions and can create a wide range of graphic for your clients which match their business ",
"We are mobile. And we make you mobile. We make responsive websites and mobile apps which compliment your business ",
"When you are hosting your website in the India you will benefit from a higher ping rate and lowest latency ",
"Our team is competent at coding web apps with keen attention to detail & intuitive functionality that is high on design & creativity",
"Content is the heart of your digital presence. We create the right content with the right focus for your business",
"Secure your site with the world's leading provider of online security and get these exclusive features at no added cost",
};
int[] images = {R.drawable.website_design, R.drawable.digita,R.drawable.domain_registration,R.drawable.graphic,
R.drawable.mob,R.drawable.server,R.drawable.software_development,R.drawable.ontent,R.drawable.ssl};
private static final String KEY_MOVIE_TITLE = "key_title";
public FragmentAction() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment.
*
* #return A new instance of fragment FragmentAction.
*/
public static FragmentAction newInstance(String movieTitle) {
FragmentAction fragmentAction = new FragmentAction();
Bundle args = new Bundle();
args.putString(KEY_MOVIE_TITLE, movieTitle);
fragmentAction.setArguments(args);
return fragmentAction;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_action,container,false);
TextView txt = (TextView)v.findViewById( R.id.textView12 );
txt.setText("\u25BA Creative & Dedicated Team");
TextView txt1 = (TextView)v.findViewById( R.id.textView13 );
txt1.setText("\u25BA Affordable Cost");
TextView txt2 = (TextView)v.findViewById( R.id.textView14 );
txt2.setText("\u25BA Maintain Long Relationship");
TextView txt3 = (TextView)v.findViewById( R.id.textView15 );
txt3.setText("\u25BA Timely Deliverly ");
context = this.getContext();
mViewPager = (ViewPager)v.findViewById(R.id.viewpager1);
mCardAdapter = new CardPagerAdapterS();
for (int i=0; i<titlesText.length; i++){
mCardAdapter.addCardItemS(new CardItemString( titlesText[i], detailsArray[i],images[i]));
}
mCardShadowTransformer = new ShadowTransformer(mViewPager, mCardAdapter);
mViewPager.setAdapter(mCardAdapter);
mViewPager.setPageTransformer(false, mCardShadowTransformer);
mViewPager.setOffscreenPageLimit(3);
viewPager = (ViewPager)v.findViewById( R.id.viewpager );
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter( this.getContext() );
viewPager.setAdapter( viewPagerAdapter );
Timer timer = new Timer( );
timer.scheduleAtFixedRate( new Mytime(),2000,4000 );
FloatingActionButton floatingActionButton = (FloatingActionButton)v.findViewById( R.id.floatingActionButton );
floatingActionButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity( new Intent( getActivity(),Registration.class ) );
}
} );
return v;
}
public class Mytime extends TimerTask{
#Override
public void run() {
getActivity().runOnUiThread( new Runnable() {
#Override
public void run() {
if(viewPager.getCurrentItem() == 0) {
viewPager.setCurrentItem( 1 );
}
else if (viewPager.getCurrentItem()== 1){
viewPager.setCurrentItem( 2 );
}
else if (viewPager.getCurrentItem()== 2){
viewPager.setCurrentItem( 3 );
}
else if (viewPager.getCurrentItem()== 3){
viewPager.setCurrentItem( 4 );
}
else {
viewPager.setCurrentItem(0);
}
}
} );
}
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Drawable movieIcon = ResourcesCompat.getDrawable(getResources(), R.drawable.webdesign, getContext().getTheme());
String movieTitle = getArguments().getString(KEY_MOVIE_TITLE);
}
}
first of all onPageSelected listener is not really good idea in this case, because it is invoked every time when viewpager' current position changes (it's good for setting toolbar title, for example).
You can add another collection for Activities which can be invoked in CardPagerAdapterS, for example:
....
private List<CardItemString> mData;
private List<Class<? extends Activity> mActivities;
and use them to create click listener in order to open activities:
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext())
.inflate(R.layout.adapter, container, false);
container.addView(view);
bind(mData.get(position), view);
CardView cardView = (CardView) view.findViewById(R.id.cardView);
if (mBaseElevation == 0) {
mBaseElevation = cardView.getCardElevation();
}
cardView.setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR);
cardView.setOnCLickListener(v-> {
context.startActivity(new Intent(context, mActivities.get(position));
});
mViews.set(position, cardView);
return view;
}
I'm developing real-time messenger application with Parse and want to display all of users in ListView. So I also want to reference if user is online or offline, I tried 'put' method to add column named "online" and put information about it. When it went wrong, I added that column myself, but it still did not work. Here it's what I tried in UserList class at all:
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseUser;
import java.util.ArrayList;
import java.util.List;
public class UserList extends AppCompatActivity {
public static ArrayList<ParseUser> userList;
public static String TAG = "UserList";
public static ParseUser user = new ParseUser();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_list);
updateUserStatus(true);
}
#Override
protected void onDestroy() {
super.onDestroy();
updateUserStatus(false);
}
#Override
protected void onResume() {
super.onResume();
loadUserList();
}
private void updateUserStatus(boolean isOnline) {
user.put("online", isOnline);
user.saveEventually();
//System.out.println("getBoolean's result : " + user.getBoolean("online"));
}
private void loadUserList() {
ParseUser.getQuery().whereNotEqualTo("username", user.getUsername()).findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
if (objects != null) {
if (objects.size() == 0) System.out.println("No user found");
userList = new ArrayList<>(objects);
ListView list = (ListView) findViewById(R.id.userList);
list.setAdapter(new UserAdapter(UserList.this));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
startActivity(new Intent(UserList.this, MainActivity.class));
finish();
}
});
}
else {
System.out.println("exception detected while loading user list");
e.printStackTrace();
}
}
});
}
}
UserAdapter class:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.parse.ParseUser;
public class UserAdapter extends BaseAdapter {
public static String TAG = "UserAdapter";
public TextView labelname;
LayoutInflater layoutInflater;
public UserAdapter(Context context){
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return UserList.userList.size();
}
#Override
public ParseUser getItem(int index) {
return UserList.userList.get(index);
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(int pos, View v, ViewGroup group) {
ParseUser c = getItem(pos);
if (v == null) {
v = layoutInflater.inflate(R.layout.chat_item, null);
}
labelname = (TextView) v;
labelname.setText(c.getUsername());
labelname.setCompoundDrawablesWithIntrinsicBounds(c.getBoolean("online") ? R.drawable.ic_online
: R.drawable.ic_offline, 0, R.drawable.arrow, 0);
return v;
}
}
I tried saveInBackground with SaveCallback, but it throws exception named:
Caused by: java.lang.IllegalArgumentException: Cannot save a ParseUser until it has been signed up. Call signUp first
But I'm puzzled more than I was 1 hour ago. I authorize my user in another class and it seems not to be problem.
This was open bug of Parse. might be possible that not solved yet. look at this and this too.
instead of saveEventually() use saveInBackground()
and
you can't do like that
ParseUser user = new ParseUser();
if you want logged user than get like this
ParseUser user = ParseUser.getCurrentUser();
and before getting logged user you must do sign up
I am currently attempting to generate a user profile in an Android application through the users existing social network data. I am using the SocialAuth library to login and pull the data out of the application and populate some text fields in a fragment.
I am currently using Facebook and Twitter for this but I am having trouble reciving the "Location" of the profile through Facebook. Twitter is able to get location successfully but Facebook simply comes up "Null" when the get request is sent out.
To complicate things when I access the Facebook account I am testing on with the example application that SocialAuth provides it is able to get the location without any problems but despite my code being identical and Twitter running the same code it won't work within my application.
Can anyone shed some light on why I am unable to retrieve the location through Facebook in my application? I will provide my relevant classes below:
LoginActivity.java
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import org.brickred.socialauth.android.DialogListener;
import org.brickred.socialauth.android.SocialAuthAdapter;
import org.brickred.socialauth.android.SocialAuthError;
import org.brickred.socialauth.android.SocialAuthListener;
import org.brickred.socialauth.Profile;
public class LoginActivity extends ActionBarActivity {
private static SocialAuthAdapter adapter;
private Button facebook_button;
private Button twitter_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
adapter = new SocialAuthAdapter(new ResponseListener());
facebook_button = (Button)findViewById(R.id.fbSignUp);
twitter_button = (Button)findViewById(R.id.twitSignUp);
facebook_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.authorize(LoginActivity.this, SocialAuthAdapter.Provider.FACEBOOK);
}
});
twitter_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.authorize(LoginActivity.this, SocialAuthAdapter.Provider.TWITTER);
}
});
}
#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_login, 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);
}
private class ResponseListener implements DialogListener {
#Override
public void onComplete(Bundle bundle) {
adapter.getUserProfileAsync(new ProfileDataListener());
}
#Override
public void onError(SocialAuthError socialAuthError) {
}
#Override
public void onCancel() {
}
#Override
public void onBack() {
}
}
private class ProfileDataListener implements SocialAuthListener<Profile> {
#Override
public void onExecute(String provider, Profile t) {
Profile profileMap = t;
Intent intent = new Intent(LoginActivity.this, HubPage.class);
intent.putExtra("provider", provider);
intent.putExtra("profile", profileMap);
startActivity(intent);
}
#Override
public void onError(SocialAuthError socialAuthError) {
}
}
}
Profile Fragment.java
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.brickred.socialauth.Profile;
import org.brickred.socialauth.android.SocialAuthAdapter;
public class ProfileFragment extends Fragment {
SocialAuthAdapter adapter;
Profile profileMap;
// Android Components
TextView name;
TextView location;
ImageView image;
// Variables
String provider_name;
//ImageLoader imageLoader;
public ProfileFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_hub_page, container, false);
profileMap = (Profile) getActivity().getIntent().getSerializableExtra("profile");
Log.d("Profile", "Validate ID = " + profileMap.getValidatedId());
Log.d("Profile", "First Name = " + profileMap.getFirstName());
Log.d("Profile", "Last Name = " + profileMap.getLastName());
Log.d("Profile", "Location = " + profileMap.getLocation());
Log.d("Profile", "Profile Image URL = " + profileMap.getProfileImageURL());
provider_name = getActivity().getIntent().getStringExtra("provider");
// Set title
name = (TextView) rootView.findViewById(R.id.profileName);
location = (TextView) rootView.findViewById(R.id.profileLocation);
image = (ImageView) rootView.findViewById(R.id.profilePic);
//imageLoader = new ImageLoader(ProfileActivity.this);
//imageLoader.DisplayImage(profileMap.getProfileImageURL(), image);
// Name
if (profileMap.getFullName() == null)
name.setText(profileMap.getFirstName() + profileMap.getLastName());
else
name.setText(profileMap.getFullName());
// Location
location.setText(profileMap.getLocation());
return rootView;
}
}
Any help would be much appreciated as I can't seem to find any solution despite hours of trying.
Im trying to use viewPager so I want to change my class from an activity to fragment, but Im getting alot of errors, so can you tell me whats wrong and what I need to do?
Here is my original activity :
package com.pickapp.pachu.pickapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.content.Intent;
import java.util.Random;
public class MainScreen extends Activity implements OnClickListener {
private TitlesDB titles;
private Button getPickUpLine;
private TextView pickUpLine;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
titles = new TitlesDB(this);
initDB();
initialize();
}
public void initialize() {
this.getPickUpLine = (Button) findViewById(R.id.bGetLine);
this.getPickUpLine.setOnClickListener(this);
this.pickUpLine = (TextView) findViewById(R.id.tvLine);
this.pickUpLine.setOnClickListener(this);
}
public void initDB() {
titles.open();
if (!this.titles.isExist()) {
titles.createEntry("The I \n Have Cancer");
titles.createEntry("The Ocean");
}
titles.close();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bGetLine:
titles.open();
Random rnd = new Random();
int index = rnd.nextInt(titles.getLength()) + 1;
pickUpLine.setText(titles.getTitleById(index));
titles.close();
break;
case R.id.tvLine:
if(!pickUpLine.getText().toString().equals(""))
{
Intent intent = new Intent(this, PickAppLine.class);
intent.putExtra("key", pickUpLine.getText().toString());
startActivity(intent);
}
break;
}
}
}
Here is what I tried :
package com.pickapp.pachu.pickapp;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by Golan on 19/08/2014.
*/
public class MainScreenFragment extends Fragment implements OnClickListener{
private TitlesDB titles;
private Button getPickUpLine;
private TextView pickUpLine;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
titles = new TitlesDB(getActivity());
initDB();
View v = getView();
initialize(v);
return inflater.inflate(R.layout.activity_main_screen, container, false);
}
public void initialize(View v) {
this.getPickUpLine = (Button) v.findViewById(R.id.bGetLine);
this.getPickUpLine.setOnClickListener(this);
this.pickUpLine = (TextView) v.findViewById(R.id.tvLine);
this.pickUpLine.setOnClickListener(this);
}
public void initDB() {
titles.open();
if (!this.titles.isExist()) {
titles.createEntry("The I \n Have Cancer");
titles.createEntry("The Ocean");
}
titles.close();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bGetLine:
titles.open();
Random rnd = new Random();
int index = rnd.nextInt(titles.getLength()) + 1;
pickUpLine.setText(titles.getTitleById(index));
titles.close();
break;
case R.id.tvLine:
if(!pickUpLine.getText().toString().equals(""))
{
Intent intent = new Intent(this, PickAppLine.class);
intent.putExtra("key", pickUpLine.getText().toString());
startActivity(intent);
}
break;
}
}
}
We won't just fix all your code. You have to do that yourself! Remove everything that you don't need at the beginning and start adding one after the other again. Fix all the errors on the way. It is hard to know what the actual problem is when everything is wrong.
One thing that I see right away that definitely does not work is this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_main_screen, container, false); // NO, NO, NO!!
titles = new TitlesDB(getActivity());
initDB();
initialize();
}
You have a return statement in the method BEFORE you have more code. That can not work. The return statement has to be at the end!