ListView/adapter throwing IndexOutOfBound - sqlite

I have a listview with a getCount() of 7. I want all 7 items to be shown regardless if any data from my database is available to populate them. If no data is available then an item should just be blank with predetermined text.
When I have not hardcoded 7 database entries beforehand to go into the 7 views then I get an indexoutofbound exception when running the app due to the 7 items not being able to be populated accordingly. This happens in ListMealsAdapter.java when method Meal currentItem = getItem(position); is called and triggers public Meal getItem(int position).
I am looking for a condition statement that I can use for my listview/adapter that can handle an empty database so that the index does not go out of bounds. Also, is the BaseAdapter suited for what I want to do?
MainActivity.java
public class MainActivity extends BaseActivity {
public static final String TAG = "MainActivity";
private ListView mListviewMeals;
private MealDAO mMealDao;
private List<Meal> mListMeals;
private ListMealsAdapter mAdapter;
private SQLiteDatabase mDatabase;
DatabaseHelper mDbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activateToolbar(1);
// initialize views
initViews();
// fill the dailyListView
mMealDao = new MealDAO(this);
mListMeals = mMealDao.getAllMeals();
mAdapter = new ListMealsAdapter(this, mListMeals, MainActivity.this);
mListviewMeals.setAdapter(mAdapter);
}
private void initViews() {
this.mListviewMeals = (ListView) findViewById(R.id.view_daily_list);
}
ListMealsAdapter.java
public class ListMealsAdapter extends BaseAdapter {
public static final String TAG = "ListMealsAdapter";
Activity mActivity;
private List<Meal> mItems;
private LayoutInflater mInflater;
public ListMealsAdapter(Context context, List<Meal> listMeals, Activity activity) {
super();
mActivity = activity;
this.setItems(listMeals);
this.mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return 7;
}
#Override
public Meal getItem(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position) : null;
}
#Override
public long getItemId(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position).getId() : position;
}
#Override
public View getView(int position, final View convertView, final ViewGroup parent) {
View v = convertView;
final ViewHolder holder;
if (v == null) {
v = mInflater.inflate(R.layout.list_item_daily, parent, false);
holder = new ViewHolder();
holder.txtDescription = (TextView) v.findViewById(R.id.txtBreakfast);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
// fill row data
Meal currentItem = getItem(position);
if (currentItem != null) {
holder.txtDescription.setText(currentItem.getDescription());
}
return v;
}
public List<Meal> getItems() {
return mItems;
}
public void setItems(List<Meal> mItems) {
this.mItems = mItems;
}
class ViewHolder {
TextView txtDescription;
}
}
Meal.java
public class Meal implements Serializable {
public static final String TAG = "Meal";
private static final long serialVersionUID = -7406082437623008161L;
private long mId;
private int mType;
private String mDescription;
public Meal() {
}
public Meal(int type, String description) {
this.mType = type;
this.mDescription = description;
}
public long getId() {
return mId;
}
public void setId(long mId) {
this.mId = mId;
}
public int getType() {
return mType;
}
public void setType(int mType) {
this.mType = mType;
}
public String getDescription() {
return mDescription;
}
public void setDescription(String mDescription) {
this.mDescription = mDescription;
}
}
MealDAO.java
public class MealDAO {
public static final String TAG = "MealDAO";
private SQLiteDatabase mDatabase;
private DatabaseHelper mDbHelper;
private Context mContext;
private String[] mAllColumns = { DatabaseHelper.COLUMN_MEAL_ID,
DatabaseHelper.COLUMN_MEAL_TYPE, DatabaseHelper.COLUMN_MEAL_DESCRIPTION};
public MealDAO(Context context) {
this.mContext = context;
mDbHelper = new DatabaseHelper(context);
// open the database
try {
open();
} catch (SQLException e) {
Log.e(TAG, "SQLException on opening database " + e.getMessage());
e.printStackTrace();
}
}
public void open() throws SQLException {
mDatabase = mDbHelper.getWritableDatabase();
}
public void close() {
mDbHelper.close();
}
public List<Meal> getAllMeals() {
List<Meal> listMeals = new ArrayList<Meal>();
Cursor query = mDatabase.rawQuery("SELECT * from meal", null);
if(query.moveToFirst()) {
do {
// Cycle through all records
Meal meal = cursorToMeal(query);
listMeals.add(meal);
} while(query.moveToNext());
}
return listMeals;
}
public Meal getMealById(long id) {
Cursor cursor = mDatabase.query(DatabaseHelper.TABLE_MEALS, mAllColumns,
DatabaseHelper.COLUMN_MEAL_ID + " = ?",
new String[] { String.valueOf(id) }, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
Meal meal = cursorToMeal(cursor);
return meal;
}
protected Meal cursorToMeal(Cursor cursor) {
Meal meal = new Meal();
meal.setId(cursor.getLong(0));
meal.setType(cursor.getInt(1));
meal.setDescription(cursor.getString(2));
return meal;
}
}

After a LOT of trial and error I finally found an acceptable solution to my problem. What I did was to add a default row to my database for the view items that I wanted to have a predetermined database entry when no data had been entered beforehand.
I then made sure to start at index 2, making sure that index 1 would be reserved for my default value. If the index comes out of bounds then the exception is caught and the default database entry will be added to the array.
public Meal getItem(int position) {
Meal result;
try {
result = (getItems() != null && !getItems().isEmpty()) ? getItems().get(position) : null;
} catch (Exception e) {
Meal default = getItem(0);
return default;
}
return result;
}
Meal currentItem = getItem(position + 1);
if (currentItem != null) {
holder.txtDescription.setText(currentItem.getDescription());
}
With that change things have been running smooth ever since. I hope this can help someone else as well.

Related

Correcting a null object reference while adding a recyclerview into a fragment

Trying to implement a recycleview inside of a fragment using a custom adapter and receiving the following error.
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference. AtStoreAdapter.getItemCount(StoreAdapter.java:xx)
I have looked around SO, but have not seen anything that is leading to a solution. Any help would be appreciated.
Android app - Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
and a few others
StoreAdapter
public class StoreAdapter extends RecyclerView.Adapter<StoreAdapter.StoreHolder>{
private LayoutInflater mInflator;
private List<Store> mStore= Collections.emptyList();
private Context mContext;
public StoreAdapter(Context mContext, List<Store> mStore){
mInflator = LayoutInflater.from(mContext);
this.mStore = mStore;
this.mContext = mContext;
}
// Simple nested class that holds the various view components for the adapter
// and as specified in *layout.xml .
public class StoreHolder extends RecyclerView.ViewHolder{
TextView mStoreTitle, mStoreDetails, mStoreCategory;
public StoreHolder (View itemView){
super(itemView);
mStoreTitle = (TextView) itemView.findViewById(R.id.title);
mStoreDetails = (TextView) itemView.findViewById(R.id.details);
mStoreCategory = (TextView) itemView.findViewById(R.id.category);
}
}
// Called when the RecyclerView needs a new RecyclerView.ViewHolder (*Holder)
// to represent an item. We inflate the XML layout and return our view (*Holder)
#Override
public StoreHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflator.inflate(R.layout.todo_list_row, parent,false);
return new StoreHolder(view);
}
// Called by RecyclerView to display the data at the specified position.
// This method needs to update the contents of the view to reflect the item at the
// given position e.g. we are updating the view here with the data
#Override
public void onBindViewHolder(StoreAdapter.StoreHolder holder, int position) {
holder.mStoreTitle.setText(mStore.get(position).getStoreTitle());
holder.mStoreDetails.setText(mStore.get(position).getStoreDetails());
holder.mStoreCategory.setText(mStore.get(position).getStoreCategory());
}
public void setData(List<Store> store){
this.mStore = store;
}
public void delete(int position){
mStore.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
return mStore.size();
}
}
StoreSectionLoader
public class StoreSectionLoader extends AsyncTaskLoader<List<Store>> {
private static final String LOG_TAG = StoreSectionLoader.class.getSimpleName();
private List<Store> mStore;
private ContentResolver mContentResolver;
private Cursor mCursor;
public StoreSectionLoader(Context context, Uri uri, ContentResolver contentResolver){
super(context);
mContentResolver = contentResolver;
}
#Override
public List<Store> loadInBackground() {
String[] projection = {BaseColumns._ID,
RetailFinderContract.RetailFinderColumns.STORE_COMPLETE,
RetailFinderContract.RetailFinderColumns.STORE_CREATED,
RetailFinderContract.RetailFinderColumns.STORE_TITLE,
RetailFinderContract.RetailFinderColumns.STORE_DETAILS,
RetailFinderContract.RetailFinderColumns.STORE_CATEGRORY};
List<Store> entry = new ArrayList<>();
Uri uri = RetailFinderContract.URI_LOCATION_TABLE;
mCursor = mContentResolver.query(uri, projection, null, null, null);
if(mCursor != null){
if(mCursor.moveToFirst()){
do {
int _id = mCursor.getInt(mCursor.getColumnIndex(BaseColumns._ID));
String store_title = mCursor.getString(
mCursor.getColumnIndex(RetailFinderContract.RetailFinderColumns.STORE_TITLE));
String store_details = mCursor.getString(
mCursor.getColumnIndex(RetailFinderContract.RetailFinderColumns.STORE_DETAILS));
String store_category = mCursor.getString(
mCursor.getColumnIndex(RetailFinderContract.RetailFinderColumns.STORE_CATEGRORY));
Store store = new Store(_id,store_title,store_details,store_category);
entry.add(store);
} while (mCursor.moveToNext());
}
}
return entry;
}
#Override
public void deliverResult(List<Store> store) {
if(isReset()){
if (mStore != null){
mCursor.close();
}
}
List<Store> oldStoreList = mStore;
if(mStore == null || mStore.size() == 0 ){
Log.d(LOG_TAG, "+++++++++++++++ No Data returned");
}
mStore = store;
if(isStarted()){
super.deliverResult(store);
}
if(oldStoreList != null && oldStoreList != store){
mCursor.close();
}
}
#Override
protected void onStartLoading() {
if(mStore != null){
deliverResult(mStore);
}
if(takeContentChanged() || mStore == null){
forceLoad();
}
}
#Override
protected void onStopLoading() {
cancelLoad();
}
#Override
protected void onReset() {
onStopLoading();
if(mCursor != null){
mCursor.close();
}
mStore = null;
}
#Override
public void onCanceled(List<Store> store) {
super.onCanceled(store);
if(mCursor != null){
mCursor.close();
}
}
#Override
public void forceLoad() {
super.forceLoad();
}
}
StoreFragment
public class StoreFragment extends Fragment implements
LoaderManager.LoaderCallbacks<List<Store>> {
private static final String LOG_TAG = StoreListFragment.class.getSimpleName();
private StoreAdapter mAdapter;
private static final int LOADER_ID = 1;
private ContentResolver mContentReslover;
private List<Store> mStore;
private Context mContext;
protected RecyclerView mRecyclerView;
private static final String TAG = "RecyclerViewFragment";
private static final String KEY_LAYOUT_MANAGER = "layoutManager";
private enum LayoutManagerType {
GRID_LAYOUT_MANAGER,
LINEAR_LAYOUT_MANAGER
}
protected LayoutManagerType mCurrentLayoutManagerType;
protected RecyclerView.LayoutManager mLayoutManager;
// end added
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
mContentReslover = getActivity().getContentResolver();
getLoaderManager().initLoader(LOADER_ID, null, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.store_list_row, container, false);
rootView.setTag(TAG);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.t_recycler);
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
if (savedInstanceState != null) {
// Restore saved layout manager type.
mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
.getSerializable(KEY_LAYOUT_MANAGER);
}
setRecyclerViewLayoutManager(mCurrentLayoutManagerType);
mAdapter = StoreAdapter(getContext(), mStore); //issue
mRecyclerView.setAdapter(mAdapter);
return rootView;
}
public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) {
int scrollPosition = 0;
// If a layout manager has already been set, get current scroll position.
if (mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
switch (layoutManagerType) {
case LINEAR_LAYOUT_MANAGER:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
default:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
}
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(scrollPosition);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save currently selected layout manager.
savedInstanceState.putSerializable(KEY_LAYOUT_MANAGER, mCurrentLayoutManagerType);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public Loader<List<Store>> onCreateLoader(int id, Bundle args) {
mContentReslover = getActivity().getContentResolver();
return new StoreSectionLoader(getActivity(), RetailFinderContract.URI_STORES_TABLE, mContentReslover);
}
#Override
public void onLoadFinished(Loader<List<Store>> loader, List<Store> store) {
mAdapter.setData(store);
mStore = store;
}
#Override
public void onLoaderReset(Loader<List<Store>> loader) {
mAdapter.setData(null);
}
}

Realm Array of Strings in Android

I have been trying to store an array of strings in Realm database programmatically as given below:
Model Class:
public class Station extends RealmObject {
private String name;
// ... Generated getters and setters ...
}
Saving Data:
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Station station1 = realm.createObject(Station.class)
station1.setName(name1);
Station station2 = realm.createObject(Station.class)
station2.setName(name2);
//goes on till station8000
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
// ...
});
Is there an alternate best way for this?
Why yes of course there is
public class Station extends RealmObject {
private String name;
// ... Generated getters and setters ...
}
and
// field variable
RealmResults<Station> stations;
// field variable
RealmChangeListener<RealmResults<Station>> changeListener = new RealmChangeListener<RealmResults<Station>>() {
#Override
public void onChange(RealmResults<Station> results) {
// handle onSuccess()
}
}
and
stations = realm.where(Station.class).findAll();
stations.addChangeListener(changeListener);
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Station station = new Station();
for(String stationName : listOfStationNames) {
station.setName(stationName);
realm.insert(station);
}
}
});
EDIT: Check out this sexy spinner.
public class DropdownSpinnerAdapter
extends BaseAdapter
implements SpinnerAdapter {
private static final String TAG = "DropdownSpinnerAdapter";
private boolean isItemSelected;
RealmResults<Station> content;
public ResultDropdownSpinnerAdapter(RealmResults<Station> objects) {
this.content = objects;
}
#Override
public int getCount() {
if(content == null || !content.isValid()) {
return 1;
}
return content.size() + 1;
}
#Override
public String getItem(int position) {
if(position <= 0) {
return "";
}
return content.get(position - 1);
}
#Override
public long getItemId(int position) {
return position;
}
public int findPosition(Station selectedItem) {
for(int i = 0, s = content.size(); i < s; i++) {
Station item = content.get(i);
if(item.equals(selectedItem)) {
return i + 1;
}
}
return 0;
}
static class ViewHolder {
TextView textView;
ImageView imageView;
public ViewHolder(View convertView) {
textView = ButterKnife.findById(convertView, R.id.dropdown_textview);
imageView = ButterKnife.findById(convertView, R.id.dropdown_arrow);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView != null) {
if(!(convertView instanceof DropdownHeaderView)) {
convertView = null;
}
}
if(convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate((isItemSelected) ? R.layout.dropdown_selected : R.layout.dropdown,
parent,
false);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.textView.setText(getItem(position).getName());
return convertView;
}
public void setItemSelected(boolean selected) {
this.isItemSelected = selected;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if(convertView != null) {
if(!(convertView instanceof DropdownView)) {
convertView = null;
}
}
if(convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.dropdown_noarrow, parent, false);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.textView.setText(getItem(position).getName());
return convertView;
}
public void updateContent(RealmResults<Station> content) {
this.content = content;
notifyDataSetChanged();
}
}

Android changing order of items run-time in Realm Recyclerview

I need to order the list of items based on a field say starredAt
I am loading the data in the recyclerview from Realm DB using RealmRecyclerView by thorbenprimke
The field changes it value on user's action i.e when user presses star button the item should be moved to top.
For this I am just updating the starredAt field of the object.
The items are already sorted by starredAt so realm loads the updated list but it randomly adds one more item to the recyclerview.
CheatSheet.java
public class CheatSheet extends RealmObject {
#PrimaryKey
private String id;
private RealmList<Item> items;
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public RealmList<Item> getItems() {
return items;
}
public void setItems(RealmList<Item> items) {
this.items = items;
}
}
Item.java
public class Item extends RealmObject {
#PrimaryKey
private String id;
private String description;
private Date starredAt;
public Item() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStarredAt() {
return starredAt;
}
public void setStarredAt(Date starredAt) {
this.starredAt = starredAt;
}
}
CheatSheetActivity.java
public class MainActivity extends AppCompatActivity {
RealmRecyclerView revItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setData();
}
private void setData() {
rvItems = (RealmRecyclerView) findViewById(R.id.rev_items);
RealmResults<Item> items = Realm.getDefaultInstance().where(CheatSheet.class)
.equalTo("id", "some-id").findFirst().getItems()
.where()
.findAllSorted("starredAt", Sort.DESCENDING);
ItemRealmListAdapter itemRealmListAdapter =
new ItemRealmListAdapter(this, items,
true, true);
rvItems.setAdapter(itemRealmListAdapter);
}
ItemRealmListAdapter.java
public class ItemRealmListAdapter extends RealmBasedRecyclerViewAdapter<Item,
ItemRealmListAdapter.ItemViewHolder> {
RealmResults<Item> mItems;
public ItemRealmListAdapter(Context context, RealmResults<Item> realmResults,
boolean automaticUpdate, boolean animateResults) {
super(context, realmResults, automaticUpdate, animateResults);
this.mItems = realmResults;
}
#Override
public ItemViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int i) {
return new ItemViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_layout_cs_text, viewGroup, false));
}
public Item getItem(int position) {
return mItems.get(position);
}
#Override
public void onBindRealmViewHolder(ItemViewHolder itemViewHolder, int position) {
itemViewHolder.txtBody.setText(getItem(position).getDescription());
if (getItem(position).getStarredAt() != null) {
itemViewHolder.imvStar.setImageResource(R.drawable.ic_star_yellow);
}
itemViewHolder.imvStar.setOnClickListener(v -> handleStarClick(v,position));
}
private void handleStarClick(View v, int position) {
if (getItem(position).getStarredAt() != null) {
((ImageView) v).setImageResource(R.drawable.ic_star);
CheatSheetStorage.unStarItem("some-id", getItem(position));
} else {
((ImageView) v).setImageResource(R.drawable.ic_star_yellow);
CheatSheetStorage.starItem("some-id", getItem(position));
}
}
public static class ItemViewHolder extends RealmViewHolder {
#Bind(R.id.txt_cheat_sheet)
TextView txtBody;
#Bind(R.id.img_star)
ImageView imvStar;
public ItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
CheatSheetStorage.java
public class CheatSheetStorage {
public static void unStarItem(String cheatSheetId, Item item) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
itemDB.setStarredAt(null);
realm.commitTransaction();
}
public static void starItem(String cheatSheetId, Item item) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
itemDB.setStarredAt(new Date());
realm.commitTransaction();
}
}
Please refer following screenshots for clearer idea :
Screenshot before starring
Screenshot after starring the sixth item
#Rohan-Peshkar - You will have to provide a animateExtraColumnName value to the adapter. For the animations, the adapter keeps track of the items and since that item's id doesn't change, the list isn't updated. With an additional column (in your case that should be the starredAt column - as long as it is stored as an Integer), the diffing algorithm will detect a change and the order is updated.
For reference: https://github.com/thorbenprimke/realm-recyclerview/blob/2835a543dce20993d8f98a4f773fa0e67132ce52/library/src/main/java/io/realm/RealmBasedRecyclerViewAdapter.java#L177
You can also check out the MainActivity in the example folder. The example changes a row's text from "ABC" to "Updated ABC" and the list recognizes the change because both the primary key and the quote field are used to basically create a composite key for diffing purposes.

android- How do I launch an Activity from a item in Reyclerview?

I am trying to launch an activity from a recyclerview's item using OnClick method. I made an interface and used getAdapterPostion in the adapter. But the Activity is not launching. Here's my code:
Interface that I created in my Adapter:
public interface Clicklistener{
public void itemClicked(View view,int position);
}
}
Setter method for ClickListener:
public void setclickListener(Clicklistener clickListener){
this.clickListener = clickListener;
}
View Holder Method where I set the OnClickListener:
public class ViewHolderListMovies extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView movieThumbnail;
private TextView movieTitle;
private TextView movieYear;
public ViewHolderListMovies(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
movieThumbnail = (ImageView) itemView.findViewById(R.id.video_poster);
movieTitle = (TextView) itemView.findViewById(R.id.video_name);
movieYear = (TextView) itemView.findViewById(R.id.video_year);
}
#Override
public void onClick(View v) {
if(clickListener!=null){
clickListener.itemClicked(v,getAdapterPosition());
}
}
The I Initialised the the interface in the fragment:
listMoviesAdapter.setclickListener(this);
At last I started an intent in in the fragment to call the needed Activity:
#Override
public void itemClicked(View view, int position) {
startActivity(new Intent(getActivity(),MovieDetailsActivity.class));
}
Any Help is appreciated. Thanks!
Initialise the setoncliklistener in method onBindViewHolder. Example, may be help
public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> {
private Context mContext;
private List<String> mDataSet;
private List<String> mIdevent;
public HistoryAdapter(Context context, List<String> dataSet, List<String> idevent, List<String> askPrice,
List<String> bidPrice, List<String> Profit) {
mContext = context;
mDataSet = dataSet;
mIdevent = idevent;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext)
.inflate(R.layout.layout_list_history, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Picasso.with(mContext).load(R.drawable.add2new).into(holder.image);
holder.text.setText(mDataSet.get(position));
holder.setClickListener(new HistoryAdapter.ViewHolder.ClickListener() {
public void onClick(View v, int pos, boolean isLongClick) {
if (isLongClick) {
// View v at position pos is long-clicked.
String poslx = pos + "";
String menax = mDataSet.get(pos);
Toast.makeText(mContext, "longclick pos. " + poslx + " pair " + menax, Toast.LENGTH_SHORT).show();
} else {
// View v at position pos is clicked.
//String possx = pos + "";
String poslx = pos + "";
String event2 = mDataSet.get(pos);
String id2 = mIdevent.get(pos);
Toast.makeText(mContext, "shortclick pos. " + poslx + " pair " + event2, Toast.LENGTH_SHORT).show();
//toggleSelection(pos);
Intent i = new Intent(mContext, HistoryCandlesActivity.class);
Bundle extras = new Bundle();
extras.putString("eventx", event2);
extras.putString("idx", id2);
extras.putInt("whatspage", 0);
i.putExtras(extras);
v.getContext().startActivity(i);
}
}
});
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public void remove(int position) {
mDataSet.remove(position);
notifyItemRemoved(position);
}
public void add(String text, int position) {
mDataSet.add(position, text);
notifyItemInserted(position);
}
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public ImageView image;
public TextView text;
private ClickListener clickListener;
public ViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
text = (TextView) itemView.findViewById(R.id.text);
// We set listeners to the whole item view, but we could also
// specify listeners for the title or the icon.
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
/* Interface for handling clicks - both normal and long ones. */
public interface ClickListener {
/**
* Called when the view is clicked.
*
* #param v view that is clicked
* #param position of the clicked item
* #param isLongClick true if long click, false otherwise
*/
public void onClick(View v, int position, boolean isLongClick);
}
/* Setter for listener. */
public void setClickListener(ClickListener clickListener) {
this.clickListener = clickListener;
}
#Override
public void onClick(View v) {
// If not long clicked, pass last variable as false.
clickListener.onClick(v, getPosition(), false);
}
#Override
public boolean onLongClick(View v) {
// If long clicked, passed last variable as true.
clickListener.onClick(v, getPosition(), true);
return true;
}
}
}

how to get the data and update to UI when new record available in SqliteDB?

I am working on a sample application by communicate with .net web service.In my application I am getting records from web service into my activity class then i am displaying entire records in ListView by using ArrayAdapter and also i am running a service class at background process for get the latest record from web service when the new records are available from web service then i am saving those records in to SQLite data base.This process is happening at back ground.Here i would like to get the latest data from SQLite DB and append to my ListView.
I have implemented Activity class as follows:
public class GetMsgsScreen extends ListActivity
{
private LayoutInflater mInflater;
private Vector<RowData> data;
RowData rd;
static String[] userName = null;
static String[] usrMessages = null;
private Integer[] imgid = null;
ShoutRepeatService bg;
////////////////////////////////////////////////////
List<Message> resultShoutMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
resultMessage = new ParseXml().convertMessages(new Model().getMessages("0"));
usrMessages = new String[resultMessage.size()];
userName = new String[resultMessage.size()];
imgid = new Integer[resultMessage.size()];
getSharedPreferences("Values", 0).edit().putString("msgid",resultMessage.get(0).getMessageID()).commit();
for(int i=0;i<resultMessage.size();i++)
{
Log.v("GetMsgsScreen", "resultMessage*******>>>>"+resultMessage.get(i).getMessageText());
Log.v("GetMsgsScreen", "resultNames*******>>>>"+resultMessage.get(i).getUserFirstName());
usrMessages[i] = resultMessage.get(i).getMessageText();
userName[i] = resultMessage.get(i).getUserFirstName();
imgid[i] = R.drawable.person;
}
///////////////////////////////////////////////////////
mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
data = new Vector<RowData>();
for(int i=0;i<userName.length;i++){
try {
rd = new RowData(i,userName[i],usrMessages[i]);
} catch (ParseException e) {
e.printStackTrace();
}
data.add(rd);
}
CustomAdapter adapter = new CustomAdapter(this, R.layout.list, R.id.usrName, data);
setListAdapter(adapter);
bindService(new Intent(GetMsgsScreen.this, RepeatService.class), mConnection, Context.BIND_AUTO_CREATE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getListView().setTextFilterEnabled(true);
}
#Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
bg = ((RepeatService.MyBinder) binder).getService();
Toast.makeText(GetMsgsScreen.this, "Connected",
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
bg = null;
}
};
public void onListItemClick(ListView parent, View v, int position, long id) {
Toast.makeText(getApplicationContext(), "You have selected "
+(position+1)+"th item", Toast.LENGTH_SHORT).show();
}
private class CustomAdapter extends ArrayAdapter<RowData> {
public CustomAdapter(Context context, int resource, int textViewResourceId, List<RowData> objects) {
super(context, resource, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
TextView name = null;
TextView messages = null;
ImageView i11=null;
RowData rowData= getItem(position);
if(null == convertView){
convertView = mInflater.inflate(R.layout.list, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
name = holder.gettitle();
name.setText(rowData.mName);
messages = holder.getdetail();
messages.setText(rowData.mMessage);
i11=holder.getImage();
i11.setImageResource(imgid[rowData.mId]);
return convertView;
}
private class ViewHolder {
private View mRow;
private TextView names = null;
private TextView messageText = null;
private ImageView i11=null;
public ViewHolder(View row) {
mRow = row;
}
public TextView gettitle() {
if(null == names){
names = (TextView) mRow.findViewById(R.id.usrName);
}
return names;
}
public TextView getdetail() {
if(null == messageText){
messageText = (TextView) mRow.findViewById(R.id.msgText);
}
return messageText;
}
public ImageView getImage() {
if(null == i11){
i11 = (ImageView) mRow.findViewById(R.id.img);
}
return i11;
}
}
}
}
I have implemented background service class as follows:
public class RepeatService extends Service
{
List<Message> resultMessage;
String[] userNameLatest = null;
String[] usrMessagesLatest = null;
String[] usrMessageID = null;
String msgID = null;
private Timer timer = new Timer();
private static final long UPDATE_INTERVAL = 500;
SQLiteDB db;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
private void pollForUpdates() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("!!!!!!!!!!!!!!!!", "service is calling");
msgID = getSharedPreferences("Values", 0).getString("msgid","");
resultMessage = new ParseXml().convertMessages(new Model().getMessages(msgID));
usrMessagesLatest = new String[resultMessage.size()];
userNameLatest = new String[resultMessage.size()];
usrMessageID = new String[resultMessage.size()];
db = new SQLiteDB();
for(int i=0;i<resultMessage.size();i++)
{
Log.v("RepeatService", "getMessageID------>"+resultMessage.get(i).getMessageID());
Log.v("RepeatService", "getMessageText------>"+resultMessage.get(i).getMessageText());
Log.v("RepeatService", "getUserFirstName------>"+resultMessage.get(i).getUserFirstName());
usrMessagesLatest[i] = resultMessage.get(i).getMessageText();
userNameLatest[i] = resultMessage.get(i).getUserFirstName();
usrMessageID[i] = resultMessage.get(i).getMessageID();
//Save the data into Sqlite db here
db.insertValues(usrMessageID[i], userNameLatest[i], usrMessagesLatest[i], RepeatService.this);
}
}
}, 0, UPDATE_INTERVAL);
Log.v(getClass().getSimpleName(), "Timer started.");
}
public class MyBinder extends Binder {
ShoutRepeatService getService()
{
return ShoutRepeatService.this;
}
}
}
The above class always run at back ground if any new record available from web service then store the record into Sqlite db.
From the above code i can save the data in to Sqlite data base then
How can i show the latest record to my ListView on My Activity class?
please any body help me with code explanation.........
I would probably use a BroadcastReceiver that is notified from the service when something new has been added. It could then update your list. Also look at LocalBroadcastManager since all the communication is in your app.

Resources