I am working on an application in which i need to implement favorites using ROOM ORM. I have different Duas in a fragment and there is a button for inserting that Dua into the Database the insertion part works fine but when i try to load the dua by clicking on the dua which i had recently added to the favorite a null pointer exception is thrown and this only happens in the case when i add more then two duas to the favorite list at the same time. Code is attached have a look BELOW is the DAO CLASS
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import com.islam.cheapapps.dua101.model.Favorite;
import java.util.List;
/**
* Created by home on 16/06/2018.
*/
#Dao
public interface FavoriteDao {
#Insert
void insert(Favorite favorite);
#Query("DELETE FROM favorite_dua")
void deleteAll();
//ORDER BY word ASC if ordering is necessary.(optional)
#Query("SELECT * from favorite_dua")
LiveData<List<Favorite>> getAllDuas();
#Query("SELECT * FROM favorite_dua WHERE position = :position AND dua_category = :dua_category")
Favorite getFavoritePosition(int position, String dua_category);
}
CLASS IN WHICH THE FAVORITE BUTTON IS CLICKED
public class ScreenSlidePageFragment extends Fragment {
JSONArray jsonArray;
FavoriteViewModel mWordViewModel;
// Variable for identification of category (0 for duas after salah, 1 for morning azkar) and so on
int id = 0;
private int pos = 0;
//Title Text View
private TextView headerTV;
//Pronunciation Text View
private TextView pronunciationTV;
//Translation Text View
private TextView translationTV;
//Benefit Text View
private TextView benefitTV;
//Reference Text View
private TextView referenceTV;
//Dua Image View
private ImageView duaIV;
//Favorite Button
private LikeButton favoriteBtn;
//Share Button
private SparkButton shareButton;
public void setPosition(int pos) {
this.pos = pos;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.dua_layout, container, false);
//Get reference to the dua title
headerTV = rootView.findViewById(R.id.title);
//Get reference to the dua pronunciation
pronunciationTV = rootView.findViewById(R.id.pronounciationTV);
//Get reference to the dua translation
translationTV = rootView.findViewById(R.id.translationTV);
//Get reference to the dua benefit
benefitTV = rootView.findViewById(R.id.benefitTV);
//Get reference to the dua reference
referenceTV = rootView.findViewById(R.id.referenceTV);
//Get reference to the dua img
duaIV = rootView.findViewById(R.id.duaIV);
//Get reference to the favorite Button
favoriteBtn = rootView.findViewById(R.id.favorite_btn);
//Get reference to the share Button
shareButton = rootView.findViewById(R.id.share_btn);
//Setting onClick Listener on share Button
shareButton.setEventListener(new SparkEventListener() {
#Override
public void onEvent(ImageView imageView, boolean b) {
}
#Override
public void onEventAnimationEnd(ImageView imageView, boolean b) {
}
#Override
public void onEventAnimationStart(ImageView imageView, boolean b) {
shareDua();
}
});
//Setting onClick listener on the fav button which will add the dua to favorite list.
favoriteBtn.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
addToFavorites();
}
#Override
public void unLiked(LikeButton likeButton) {
}
});
// Function for getting data of a specific category
getData();
// Function for setting data into the view
setData();
mWordViewModel = ViewModelProviders.of(this).get(FavoriteViewModel.class);
return rootView;
}
// Getting Data for a specific category
private void getData() {
id = getActivity().getIntent().getIntExtra("position", 0);
switch (id) {
case 0:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 1:
readData(this.getResources().openRawResource(R.raw.c1));
break;
case 2:
readData(this.getResources().openRawResource(R.raw.c2));
break;
case 3:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 4:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 5:
readData(this.getResources().openRawResource(R.raw.c0));
break;
default:
break;
}
}
/**
* Reading data from the JSON array
*/
private void readData(InputStream in) {
StringBuilder text = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader((new InputStreamReader(in)));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
jsonArray = new JSONArray(text.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Set Data depending upon the position of view pager
*/
private void setData() {
try {
JSONArray tempJson = jsonArray.getJSONArray(this.pos);
duaIV.setImageResource(getResources().getIdentifier(tempJson.getString(3).trim().substring(0, tempJson.getString(3).indexOf(".png")), "drawable", getActivity().getPackageName()));
headerTV.setText(tempJson.getString(0).trim());
pronunciationTV.setText(tempJson.getString(3).trim());
translationTV.setText(tempJson.getString(9).trim());
benefitTV.setText(tempJson.getString(12).trim());
referenceTV.setText(tempJson.getString(11).trim());
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* A share intent is fired and gives choice to user for sharing the current dua using the applications
* that are present in his mobile
*/
private void shareDua() {
/*try {
sharingText = mJsonArray.getJSONObject(currPos).getString("seq") + "\n" +
mJsonArray.getJSONObject(currPos).getString("narator") + "\n" +
mJsonArray.getJSONObject(currPos).getString("hadith");
} catch (JSONException e) {
e.printStackTrace();
}*/
Intent sharingIntent = new Intent();
sharingIntent.setAction(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
// sharingIntent.putExtra(Intent.EXTRA_TEXT, sharingText);
startActivity(Intent.createChooser(sharingIntent, "Share using"));
}
//Add dua to favorite on pressing the favorite button
private void addToFavorites() {
String dua_category = "";
switch (id) {
case 0:
dua_category = "Duas after Salah";
break;
case 1:
dua_category = "Morning Azkar";
break;
case 2:
dua_category = "Evening Azkar";
break;
case 3:
dua_category = "Rabbana Duas";
break;
case 4:
dua_category = "Essential Duas";
break;
case 5:
dua_category = "Ruquiya";
break;
default:
dua_category = "";
break;
}
Favorite favorite = new Favorite(headerTV.getText().toString(),
pronunciationTV.getText().toString(), dua_category, this.pos);
Toast.makeText(this.getContext().getApplicationContext(), "Position : " + this.pos + "Category : "
+ dua_category
, Toast.LENGTH_SHORT).show();
mWordViewModel.insert(favorite);
}
}
THE CLASS IN WHICH THE ONCLICK FOR FAVORITE ITEM WHEN THE ITEM IS ALREADY ADDED TO THE LIST IS IMPLEMENTED
public class FavoriteAdapter extends
RecyclerView.Adapter<FavoriteAdapter.MyViewHolder> {
private final LayoutInflater mInflater;
private Context mContext;
private List<Favorite> mDuas; // Cached copy of words
String cat = "";
public FavoriteAdapter(Context mContext) {
this.mContext = mContext;
mInflater = LayoutInflater.from(mContext);
}
#Override
public FavoriteAdapter.MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = mInflater.inflate(R.layout.favorite_single_item, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(FavoriteAdapter.MyViewHolder holder, int position) {
// Variable for holding the position of the current view that was clicked
final int temp = position;
if (mDuas != null) {
Favorite current = mDuas.get(position);
holder.favoriteHeader.setText(current.getHeader());
holder.favoritePronunciation.setText(current.getDua_pronunciation());
cat = current.getDua_category();
} else {
// Covers the case of data not being ready yet.
holder.favoriteHeader.setText("No Word");
}
holder.favoriteCV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Thread(new Runnable() {
#Override
public void run() {
FavoriteRoomDatabase db = FavoriteRoomDatabase.getDatabase(mContext);
FavoriteDao mFavoriteDao = db.favoriteDao();
Favorite f = mFavoriteDao.getFavoritePosition(temp, cat);
////////////////////////// TEST LOGIC //////////////////////////////
Intent intent = new Intent(mContext, ScreenSlidePagerActivity.class);
intent.putExtra("fav", "favorite");
intent.putExtra("category", f.getDua_category());
intent.putExtra("position", f.getPosition());
mContext.startActivity(intent);
////////////////////////////////////////////////////////////////////
}
}).start();
}
});
}
public void setDuas(List<Favorite> duas) {
mDuas = duas;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (mDuas != null) {
return mDuas.size();
} else {
return 0;
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView favoriteHeader, favoritePronunciation;
public ImageView favoriteImage;
public CardView favoriteCV;
public MyViewHolder(View itemView) {
super(itemView);
favoriteCV = itemView.findViewById(R.id.favoriteCV);
favoriteHeader = itemView.findViewById(R.id.favorite_header);
favoritePronunciation = itemView.findViewById(R.id.favorite_pronunciation);
favoriteImage = itemView.findViewById(R.id.favorite_image);
}
}
}
Related
I have an Android Activity which has a tab-layout(with four fragments), and first fragment have a search function which search the data through a backend service. When it's success in getting data, then it should update other fragments with relevant data(recycler views and text views). But i cannot get an idea of how to work this thing around. I'll provide what i have done so far, let me know what am i doing wrong and how should i progress. A Code example is more than welcome.
What i have tried so far is within my search fragment, when the search function retrieves success data it will show a list item first of the users profile data. When on click on that item the whole activity will restart and the data is being binded to all the other fragments. What i need to achieve now is without refreshing nor restarting the whole activity, pass the data to relevant fragments and update the views.
Collection Activity is the holder activity for my four fragments of the tab layout
In User Profile / Search Fragment
/**this updates the view from customer adapters data passing**/
public static UserProfileFragment newInstance(CustomerDTO commonCustomerDTOList, ArrayList<ContractDTO> commonContractDTOArrayList) {
UserProfileFragment fragment = new UserProfileFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("CUS_DATA", commonCustomerDTOList);
bundle.putSerializable("LOAN_DATA", commonContractDTOArrayList);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_user_profile, container, false);
...
if (getArguments() != null) {
CustomerDTO commonCustomerDTOList = (CustomerDTO) getArguments().getSerializable("CUS_DATA");
setCustomerData(commonCustomerDTOList);
NIC_NUMBER = ((CollectionActivity) Objects.requireNonNull(getActivity())).NIC_NUMBER;
sharedPreferences = getActivity().getSharedPreferences(SharedValue.MYSESSION, Context.MODE_PRIVATE);
}
return view;
}
/** set customer data from search result**/
#SuppressLint("SetTextI18n")
private void setCustomerData(CustomerDTO customerDTO) {
if (customerDTO != null) {
tvNic.setText(customerDTO.getNicNumber());
txtFullName.setText(customerDTO.getTitle() + " " + customerDTO.getInitials() + " " + customerDTO.getLastName());
txtMobile.setText(customerDTO.getMobileNo());
tvAddress1.setText(customerDTO.getAddress().split("%")[0] + ",");
tvAddress2.setText(customerDTO.getAddress().split("%")[1] + ",");
tvAddress3.setText(customerDTO.getAddress().split("%")[2] + "");
}
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.btn_search_sUP:
if (AppStatus.getInstance(Objects.requireNonNull(this.getActivity())).isOnline()) {
/**
* Internet is available, Toast It!
*/
if (sSearchCriterion.equals("NIC (NEW/OLD)")) {
if (Validation.isValidNic(editTextSearch.getText().toString().trim().toUpperCase())) {
} else {
editTextSearch.setError("Enter Valid NIC Number");
return;
}
}
showProgress();
SharedPreferences sharedPreferences = this.getActivity().getSharedPreferences(SharedValue.MYSESSION, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(SharedValue.MYSESSION_NIC_NUMBER, editTextSearch.getText().toString().trim().toUpperCase());
editor.putString(SharedValue.MYSESSION_MODULE_CODE, pProductType);
editor.putString(SharedValue.MYSESSION_SEARCH_TYPE, catNormal);
editor.apply();
boolean isLoad = new Handler().postDelayed(() -> {
String SearchMode = "";
int searchCriteriaType = SelectionCriteriaType.getSearchCriteriaType(sSearchCriterion);
if (searchCriteriaType == 1) {
SearchMode = SelectionCriteriaType.getSearchMode(SelectionCriteriaType.NIC);
} else {
SearchMode = SelectionCriteriaType.getSearchMode(SelectionCriteriaType.OTHER);
}
String CustomerCode = editTextSearch.getText().toString().trim().toUpperCase();
if (!CustomerCode.isEmpty()) {
boolean isValidNic = Validation.isValidNic(CustomerCode);
switch (searchCriteriaType) {
case 1:
if (!sSearchCriterion.equals("NIC (NEW/OLD)")) {
isValidNic = true;
getLoanDetails(pProductType, "1", String.valueOf(searchCriteriaType), CustomerCode);
} else {
getLoanDetails(pProductType, catNormal, String.valueOf(searchCriteriaType), CustomerCode);
}
break;
case 2:
isValidNic = true;
getLoanDetails(pProductType, SearchMode, String.valueOf(searchCriteriaType), CustomerCode);
break;
}
if (isValidNic) {
} else {
hideProgress();
editTextSearch.setError("Enter Valid NIC Number");
}
} else {
hideProgress();
}
hideProgress();
this.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}, 8000);
} else {
/**
* Internet is NOT available, Toast It!
*/
Toasty.error(this.getActivity(), "Please Connect to Internet!", Toast.LENGTH_SHORT).show();
}
break;
}
}
...
private void getLoanDetails(String moduleCode, String searchMode, String searchType, String searchCode) {
System.out.println("call loan details...");
CommonUtils.hideKeyboardFrom(this.getActivity(), view);
ArrayList<ContractDTO> contractVehicleDTOArrayListClear = new ArrayList<>();
ArrayList<CustomerDTO> customerDTOArrayListClear = new ArrayList<>();
CustomerAdapter customerAdapter = new CustomerAdapter(this.getActivity(), customerDTOArrayListClear, contractVehicleDTOArrayListClear, searchCode, moduleCode);
listViewCustomerList.setAdapter(customerAdapter);
customerAdapter.notifyDataSetChanged();
try {
showProgress();
String param59 = moduleCode + "|" + searchMode + "|" + searchType + "|" + searchCode;
new ISOConverter(new RResponce() {
#Override
public void get61and62Response(String res1, String res2) {
if (res1.trim().isEmpty() || res2.trim().isEmpty()) {
CommonAlert.showAlertFailure(getActivity(), "No Details Found...");
search_result_card.setVisibility(View.GONE);
} else {
CustomerDTO customerDTO = null;
if (sSearchCriterion.equals("BR NUMBER")) {
customerDTO = new CustomerDTO(res1, "");
} else {
customerDTO = new CustomerDTO(res1);
}
ArrayList<ContractDTO> contractDTOArrayList = new ContractDTO().getObjectArrayList(res2);
ArrayList<CustomerDTO> customerDTOArrayList = new ArrayList<>();
customerDTOArrayList.add(customerDTO);
CustomerAdapter customerAdapter = new CustomerAdapter(getActivity(), customerDTOArrayList, contractDTOArrayList, searchCode, pProductType);
listViewCustomerList.post(() -> {
listViewCustomerList.setAdapter(customerAdapter);
customerAdapter.notifyDataSetChanged();
});
if (customerAdapter.getCount() > 0) {
hideProgress();
search_result_card.setVisibility(View.VISIBLE);
setCustomerData(customerDTO);
}
hideProgress();
}
}
#Override
public void get39Response(String responseCode) {
System.out.println(responseCode);
}
#Override
public void get63Response(String error) {
System.out.println(error);
if (!error.trim().isEmpty()) {
new ShowMessageAsync(getActivity(), error, ShowMessageAsync.FAILED).execute();
}
}
}).convertToISO(
this.getActivity(),
MTITransaction.GET_CALL,
MTITransaction.MTI_GET,
ISOProcessCode.TRANS_CODE_LOAN_SEARCH,
"null", param59, "");
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Customer Adapter
Context mContext;
List<CustomerDTO> customerDTOList;
LayoutInflater inflater;
String NicNumber;
String moduleCode;
ArrayList<ContractDTO> contractDTOArrayList;
UserProfileFragment userProfileFragment;
public CustomerAdapter(Context mContext, List<CustomerDTO> customerDTOList, ArrayList<ContractDTO> contractDTOArrayList, String NicNumber,String moduleCode) {
this.mContext = mContext;
this.customerDTOList = customerDTOList;
this.contractDTOArrayList = contractDTOArrayList;
this.NicNumber = NicNumber;
this.moduleCode = moduleCode;
inflater = LayoutInflater.from(mContext);
}
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
...
holder.imageButton.setOnClickListener(v -> {
Intent intent = new Intent(mContext, CollectionActivity.class);
// Intent intent = new Intent("Pass Searched Data");
// Pass all data arrearsList
// intent.setAction("Pass Searched Data");
intent.putExtra(DataparsingValue.VARIABLE_NIC_NUMBER, NicNumber);
intent.putExtra(DataparsingValue.VARIABLE_CUS_DATA, customerDTOList.get(position));
intent.putExtra(DataparsingValue.VARIABLE_LOAN_DATA, contractDTOArrayList);
intent.putExtra(DataparsingValue.MODULE_CODE, moduleCode);
// intent.putExtra(DataparsingValue.VARIABLE_LOAN_WITH_VEHICLE_DATA, contractVehicleDTOArrayList);
// Pass all data flag
// Start SingleItemView Class
mContext.startActivity(intent);
});
return convertView;
}
DownPayment Fragment
//update the view using
public static DownPaymentFragment newInstance(CustomerDTO commonCustomerDTOList, ArrayList<ContractDTO> commonContractDTOArrayList) {
DownPaymentFragment fragment = new DownPaymentFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("CUS_DATA", commonCustomerDTOList);
bundle.putSerializable(DataparsingValue.VARIABLE_LOAN_WITH_VEHICLE_DATA, commonContractDTOArrayList);
fragment.setArguments(bundle);
return fragment;
}
Receipts Fragment
//Update the list using
public static ReceiptingFragment newInstance(CustomerDTO commonCustomerDTOList, ArrayList<ContractDTO> commonContractDTOArrayList) {
ReceiptingFragment fragment = new ReceiptingFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(DataparsingValue.VARIABLE_CUS_DATA, commonCustomerDTOList);
bundle.putSerializable(DataparsingValue.VARIABLE_LOAN_DATA, commonContractDTOArrayList);
fragment.setArguments(bundle);
return fragment;
}
I expect to Load the data from Search results to the Tab layout's relevant fragments without restarting the Whole activity.
I'm trying to make a laundry ordering application. I've made it to the order process, at the end of the order process, the user clicks the next button to checkout the ordered results, I have successfully made the checkout results, but what I made is still in one variable string. how to put the checkout results into an array variable so that I can post the results in the form of JSONArray?
HERE IS MY ORDER ACTIVITY CODE :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_produk);
// menghubungkan variablel pada layout dan pada java
listProduk = (ListView)findViewById(R.id.list_produk);
swipeProduct = (SwipeRefreshLayout)findViewById(R.id.swipeProduct);
radioExpress = (RadioButton)findViewById(R.id.radio_express);
radioReguler = (RadioButton)findViewById(R.id.radio_regular);
tvTotal = (TextView)findViewById(R.id.total);
next = (Button)findViewById(R.id.button_next);
actionBar = getSupportActionBar();
laundry_id = getIntent().getStringExtra(TAG_LAUNDRY_ID);
// untuk mengisi data dari JSON ke dalam adapter
productAdapter = new CheckboxAdapter(this, (ArrayList<ProductModel>) productList, this);
listProduk.setAdapter(productAdapter);
listProduk.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
productAdapter.setCheckBox(position);
}
});
// menampilkan widget refresh
swipeProduct.setOnRefreshListener(this);
swipeProduct.post(new Runnable() {
#Override
public void run() {
swipeProduct.setRefreshing(true);
productList.clear();
tvTotal.setText(String.valueOf(0));
radioReguler.isChecked();
regular = true;
productAdapter.notifyDataSetChanged();
callProduct();
}
}
);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
private void formSubmit(String hasil){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.form_submit, null);
dialog.setView(dialogView);
dialog.setIcon(R.mipmap.ic_launcher);
dialog.setTitle("Menu Yang Dipilih");
dialog.setCancelable(true);
txtnamaProduk = (TextView) dialogView.findViewById(R.id.txtNama_produk);
txtnamaProduk.setText(hasil);
dialog.setNeutralButton("CLOSE", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
AND HERE IS THE CODE OF THE RESULT :
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
in my code above, I still use the variable checkbox to accommodate all the results of the order chosen by the user. how to put all the result into array variable so i can post to server as a JSONArray? Please help me to solve this problem. because i'm still a beginner in android.
HERE IS MY ADAPTER CODE IF NEEDED :
public class CheckboxAdapter extends BaseAdapter{
private Context context;
private ArrayList<ProductModel> productItems;
ProdukLaundry produk;
public CheckboxAdapter(Context context, ArrayList<ProductModel> items, ProdukLaundry produk) {
this.context = context;
this.productItems = items;
this.produk = produk;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getCount() {
return productItems.size();
}
#Override
public Object getItem(int position) {
return productItems.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
final ProductModel items = productItems.get(position);
if(view == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_produk, null, true);
viewHolder.checkBox = (CheckBox) view.findViewById(R.id.checkBox_productName);
viewHolder.decrease = (TextView) view.findViewById(R.id.decrease_product);
viewHolder.count = (TextView) view.findViewById(R.id.count_product);
viewHolder.increase = (TextView) view.findViewById(R.id.increase_product);
viewHolder.price = (TextView) view.findViewById(R.id.product_price);
view.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.checkBox.setText(items.getProduct_name());
viewHolder.price.setText(items.getProduct_price());
viewHolder.count.setText(String.valueOf(items.getCountProduct()));
//fungsi untuk set posisi textview + dan -
viewHolder.increase.setTag(R.integer.btn_plus_view, view);
viewHolder.increase.setTag(R.integer.btn_plus_pos, position);
viewHolder.decrease.setTag(R.integer.btn_minus_view, view);
viewHolder.decrease.setTag(R.integer.btn_minus_pos, position);
//fungsi untuk disable textview + dan - jika checkbox tidak di klik
viewHolder.decrease.setOnClickListener(null);
viewHolder.increase.setOnClickListener(null);
if(items.isCheckbox()){
viewHolder.checkBox.setChecked(true);
viewHolder.increase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View) viewHolder.increase.getTag(R.integer.btn_plus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.increase.getTag(R.integer.btn_plus_pos);
int countProduct = Integer.parseInt(tv.getText().toString()) + 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.tambah(pos);
}
});
viewHolder.decrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View)viewHolder.decrease.getTag(R.integer.btn_minus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.decrease.getTag(R.integer.btn_minus_pos);
int total = productItems.get(pos).getCountProduct();
if (total>0){
int countProduct = Integer.parseInt(tv.getText().toString()) - 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.kurang(pos);
}
}
});
} else {
viewHolder.checkBox.setChecked(false);
//fungsi untuk reset jumlah harga dan produk pada checkbox
String count = viewHolder.count.getText().toString();
int jumlah = Integer.parseInt(count);
int harga = Integer.parseInt(productItems.get(position).getProduct_price());
int kurang = jumlah * harga;
viewHolder.count.setText("0");
productItems.get(position).setCountProduct(0);
produk.kurangCheckbox(kurang);
}
return view;
}
public ArrayList<ProductModel> getAllData(){
return productItems;
}
public void setCheckBox(int position){
ProductModel items = productItems.get(position);
items.setCheckbox(!items.isCheckbox());
notifyDataSetChanged();
}
static class ViewHolder{
TextView decrease, count, increase, price;
CheckBox checkBox;
}
}
just create getter setter method of Arraylist like below
CompleteOrder:-
public class CompleteOrder {
List<OrderItem> order_items;
public List<OrderItem> getOrder_items() {
return order_items;
}
public void setOrder_items(List<OrderItem> order_items) {
this.order_items = order_items;
}
}
Create another Getter setter class of variable you want to add in arraylist
OrderItem:-
public class OrderItem {
String product_name;
int product_total;
public OrderItem(String product_name, int product_total) {
this.product_name = product_name;
this.product_total = product_total;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getProduct_total() {
return product_total;
}
public void setProduct_total(int product_total) {
this.product_total = product_total;
}
}
Now in your onClick method just create new List as below
public void onClick(View view) {
String checkbox = "";
CompleteOrder completeOrder=new CompleteOrder();
List<OrderItem> masterProductorderCount=new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
masterProductorderCount.add(new OrderItem(holder.getProduct_name(),total);
}
}
completeOrder.setOrder_items(masterProductorderCount);
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(completeOrder);//pass object of CompleteOrder
}
});
CompleteOrder object give JSON output as below
{
"CompleteOrder":[
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
}
]
}
make a model that contains product name , total and etc,
then put each data into an object and put each object into an array
finally use Gson to map properties to model / list of models or the other way around.
ArrayList<Model> list = new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
Model model = new Model();
model.productName = hold.getProduct_name();
model.total = total;
list.add(model);
}
}
String jsonArray = Gson().toJson(list);
You need to create a JSONObject for each entry in the JSONArray.
As far as I can see this should take care of it:
public void onClick(View view) {
String checkbox = "";
JSONArray jsonArray = new JSONArray();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
JSONObject jsonObj = new JSONObject();
jsonObj.put("product_name", hold.getProduct_name());
jsonObj.put("product_total", total);
jsonArray.put(jsonObj);
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
String jsonArrayString = jsonArray.toString();
formSubmit(dipilih);
}
Depending on your data the resulting string from jsonArrayString would be:
{[
{"product_name":"product1","product_total":1},
{"product_name":"product2","product_total":2},
{"product_name":"product3","product_total":3}
]}
I really do not know what you intend on doing with the JSON data so I just created a String "jsonArrayString".. do what ever you need to with it.
I really need your help. I've searched Google many days with many keywords, but I couldn't get it. So, I decided to ask to you.
So, here it is. Actually, I have one button in RecyclerView, but this button is repeated as much amount of data available, there are: Button with text "Baca 3x", "Baca 4x", and so on. I want, if I click button with text "Baca 3x" 3 times, it will change to "Baca 2x" >> "Baca 1x" >> remove item. Also if I click button with text "Baca 4x" 4 times, it will change to "Baca 3x" >> "Baca 2x" >> "Baca 1x" >> remove item.
But my problem is, I can't treat every button with different treatment, because every time the item has been deleted, position of data changes automatically. Because of this, I can't get specific button. For example: There is two button,
1. Button "Baca 3x" on position 0
2. Button "Baca 4x" on position 1
If button "Baca 3x" on position 0 has been deleted, so button "Baca 4x" changed it's position automatically to 0. The problem lays here.
Until now I just get every button based on their positions, which is a problem for me. Because of this I am thinking about How to Delete Item Without Deleting Position in Recycler View? Can you guys solve my problem? Should I use DiffUtil?And how to use it? Below the complete code I use:
ModelDoa.java
public class ModelDoa {
public static final int DOA_PAGI = 0;
public static final int DOA_SORE = 1;
public static final int DOA_MASJID = 2;
public static final int DOA_BANGUNT = 3;
public static final int DOA_MAU_TIDUR = 4;
private String mName;
private String bName;
private int mType;
public ModelDoa(String name, String butong, int type) {
this.mName = name;
this.bName = butong;
this.mType = type;
}
public String getName() {
return mName;
}
public void setName(String name) {
this.mName = name;
}
public int getType() {
return mType;
}
public void setType(int type) { this.mType = type; }
public String ambilName() {
return bName;
}
public void setNama(String butonk) {
this.bName = butonk;
}
}
AdapterDoa.java
public class AdapterDoa extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public List<ModelDoa> mList;
public AdapterDoa(List<ModelDoa> list) {
this.mList = list;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case DOA_PAGI:
View vieu = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
PagiViewHolder rcv = new PagiViewHolder(vieu, this);
return rcv;
case DOA_SORE:
View doa = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
SoreViewHolder mdoa = new SoreViewHolder(doa);
return mdoa;
case DOA_MASJID:
View dMasjid = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
MasjidViewHolder mMasjid = new MasjidViewHolder(dMasjid);
return mMasjid;
case DOA_BANGUNT:
View dBangunt = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
BanguntViewHolder mBangunt = new BanguntViewHolder(dBangunt);
return mBangunt;
case DOA_MAU_TIDUR:
View regut = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
MauTidurViewHolder turu = new MauTidurViewHolder(regut);
return turu;
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ModelDoa object = mList.get(position);
if (object != null) {
switch (object.getType()) {
case DOA_PAGI:
((PagiViewHolder) holder).mTitle.setText(object.getName());
((PagiViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_SORE:
((SoreViewHolder) holder).mTitle.setText(object.getName());
((SoreViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_MASJID:
((MasjidViewHolder) holder).mTitle.setText(object.getName());
((MasjidViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_BANGUNT:
((BanguntViewHolder) holder).mTitle.setText(object.getName());
((BanguntViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_MAU_TIDUR:
((MauTidurViewHolder) holder).mTitle.setText(object.getName());
((MauTidurViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
}
}
}
public void deleteItem(int position) {
mList.remove(position); // hapus list
notifyItemRemoved(position); // hapus tampilan
// notifyItemRangeChanged( position, mList.size());
}
#Override
public int getItemCount() {
if (mList == null)
return 0;
return mList.size();
}
#Override
public int getItemViewType(int position) {
if (mList != null) {
ModelDoa object = mList.get(position);
if (object != null) {
return object.getType();
}
}
return 0;
}
}
PagiViewHolder.java
public class PagiViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public Button tombolbaca;
public Button teksbaca;
public Button tombolshare;
private RelativeLayout rl2;
private int klik10 = 10;
private AdapterDoa myAdapter;
public PagiViewHolder(View itemView, AdapterDoa myAdapter) {
super(itemView);
this.myAdapter = myAdapter;
itemView.setOnClickListener(mainViewClickListener);
mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
tombolbaca = (Button) itemView.findViewById(R.id.buttonbaca);
tombolshare = (Button) itemView.findViewById(R.id.buttonshare);
tombolbaca.setOnClickListener(bacaClickListener);
tombolshare.setOnClickListener(shareClickListener);
rl2 = (RelativeLayout) itemView.findViewById(R.id.relmasjid);
}
private View.OnClickListener bacaClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
teksbaca = (Button) v.findViewById(R.id.buttonbaca);
// Baca 10x
if( getAdapterPosition() ==0 ) {
klik10--;
teksbaca.setText("Baca " + klik10 + "x");
if (klik10 <= 0)
{
// modify listItems however you want... add, delete, shuffle, etc
myAdapter.deleteItem(getAdapterPosition());
}
}
} // onclick
};
private View.OnClickListener shareClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do button click handling here
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, mTitle.getText().toString() + "\n \n download aplikasinya di: http://www.tauhid.or.id" );
sendIntent.setType("text/plain");
Intent.createChooser(sendIntent,"Share via");
v.getContext().startActivity(sendIntent);
}
};
private View.OnClickListener mainViewClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do button click handling here
}
};
}
DoaPagi.java
public class DoaPagi extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doa_pagi);
// toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//this line shows back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
List<ModelDoa> rowListItem = getData();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(DoaPagi.this);
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
AdapterDoa rcAdapter = new AdapterDoa(rowListItem);
mRecyclerView.setAdapter(rcAdapter);
}
private List<ModelDoa> getData() {
String[] data = getResources().getStringArray(R.array.doapagi);
String[] baca = getResources().getStringArray(R.array.bacapagi);
List<ModelDoa> list = new ArrayList<ModelDoa>();
for (int i = 0; i < data.length; i++) {
list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI));
}
return list;
}
// Agar back button pada halaman induk settings berfungsi
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
UPDATE (FIX CODE) By: Krishna Sharma:
https://github.com/seadclark/RecyclerViewWithButtonClicks
Here is the fix. just update the ModelDoa constructor as below. I have verified myself and working as expected now. Also sent you pull request on github.
public ModelDoa(String name, String butong, int type) {
this.mName = name;
this.bName = butong;
this.mType = type;
String[] data = butong.split("\\s");
if (data.length > 0) {
String count = data[1].substring(0, data[1].length() - 1);
read10 = Integer.parseInt(count);
}
}
Instead of removing the item from your list AND updating the interface, have two methods. One of them (deleteItem) will only delete the item and the other (deleteItemAndUpdate) will delete the item and update the interface.
public void deleteItem(int position) {
mList.remove(position); // hapus list
}
public void deleteItemAndUpdate(int position) {
mList.remove(position); // hapus list
notifyItemRemoved(position); // hapus tampilan
}
In the future, you can decide whether you want to only remove the item from your list OR remove the item and update the UI.
EDIT 1:
You need to keep track of the amount of times that each item was clicked. We can call this value readCount. Every time that the item is clicked, we subtract 1 from this value. When this value reaches 0, we remove it from the list.
ModelDoa:
public class ModelDoa {
private int readCount = 10;
public int getReadCount() {
return this.readCount;
}
public void setReadCount(int readCount) {
this.readCount = readCount;
}
}
PagiViewHolder:
private View.OnClickListener bacaClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
teksbaca = (Button) v.findViewById(R.id.buttonbaca);
ModelDoa modelDoa = mAdapter.getItem(getAdapterPosition());
if (modelDoa != null) {
modelDoa.setReadCount(modelDoa.getReadCount() - 1);
if (modelDoa.getReadCount() <= 0) {
myAdapter.deleteItem(getAdapterPosition());
}
teksbaca.setText("Baca " + modelDoa.getReadCount() + "x");
}
}
};
AdapterDoa:
public ModelDoa getItem(int position) {
if (position > -1 && position < getItemCount()) {
return this.mList.get(position);
} else {
return null;
}
}
EDIT 2:
The idea is to set the readCount variable when you instantiate the object. You do not have multiple variables that do the same thing. You just change the single readCount variable to be either 7 or 10 when you are creating it and use the same getItem method when retrieving the model (not variable!) itself.
ModelDoa:
public class ModelDoa {
private String name;
private String butong;
private int type;
private int readCount;
public ModelDoa(String name, String butong, int type, int readCount) {
this.mName = name;
this.bName = butong;
this.mType = type;
this.readCount = readCount;
}
public int getReadCount() {
return this.readCount;
}
public void setReadCount(int readCount) {
this.readCount = readCount;
}
}
DoaPagi:
private List<ModelDoa> getData() {
String[] data = getResources().getStringArray(R.array.doapagi);
String[] baca = getResources().getStringArray(R.array.bacapagi);
List<ModelDoa> list = new ArrayList<ModelDoa>();
for (int i = 0; i < data.length; i++) {
// Here is where you would set the value of readCount.
list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI, i));
}
return list;
}
i have some problem with my JSON code.
I want to display a list that contain text and image. The text and image stored on my online database, i using JSON for taking them down to my android app.
The JSON doesn't display any error, the text are displayed but the image are not appear.
I check the logcat and there's no error for this process. I using viewAdapter for displaying the image on the list.
Please master help me, can you gimme some simple explanation how to solve this??
Thanks...
NB. This is my code for HomeFragment.java (where i doing the JSON).
public class HomeFragment extends Fragment implements InternetConnectionListener, ApiHandler.ApiHandlerListener {
private static final String ARG_SECTION_NUMBER = "section_number";
private final int CATEGORY_ACTION = 1;
private CategorySelectionCallbacks mCallbacks;
private ArrayList<Category> categoryList;
private ListView categoryListView;
private String Error = null;
private InternetConnectionListener internetConnectionListener;
public HomeFragment() {
}
public static HomeFragment newInstance(int sectionNumber) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((HomeActivity) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
try {
mCallbacks = (CategorySelectionCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement CategorySelectionCallbacks.");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
categoryListView = (ListView) rootView.findViewById(R.id.categoryListView);
return rootView;
}
#Override
public void onResume() {
super.onResume();
if (UtilMethods.isConnectedToInternet(getActivity())) {
initCategoryList();
} else {
internetConnectionListener = (InternetConnectionListener) HomeFragment.this;
showNoInternetDialog(getActivity(), internetConnectionListener,
getResources().getString(R.string.no_internet),
getResources().getString(R.string.no_internet_text),
getResources().getString(R.string.retry_string),
getResources().getString(R.string.exit_string), CATEGORY_ACTION);
}
}
public class getCategList extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
/**
* json is populating from text file. To make api call use ApiHandler class
*
* <CODE>ApiHandler apiHandler = new ApiHandler(this, URL_GET_CATEGORY);</CODE> <BR>
* <CODE>apiHandler.doApiRequest(ApiHandler.REQUEST_GET);</CODE> <BR>
*
* You will get the response in onSuccessResponse(String tag, String jsonString) method
* if successful api call has done. Do the parsing as the following.
*/
URL hp = null;
try {
hp = new URL(
getString(R.string.liveurl) + "foodcategory.php");
Log.d("URL", "" + hp);
URLConnection hpCon = hp.openConnection();
hpCon.connect();
InputStream input = hpCon.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(input));
String x = "";
x = r.readLine();
String total = "";
while (x != null) {
total += x;
x = r.readLine();
}
Log.d("UR1L", "" + total);
JSONArray j = new JSONArray(total);
Log.d("URL1", "" + j.length());
categoryList = new ArrayList<Category>();
for (int i = 0; i < j.length(); i++) {
Category category = new Category();// buat variabel category
JSONObject Obj;
Obj = j.getJSONObject(i); //sama sperti yang lama, cman ini lebih mempersingkat karena getJSONObject cm d tulis sekali aja disini
category.setId(Obj.getString(JF_ID));
category.setTitle(Obj.getString(JF_TITLE));
category.setIconUrl(Obj.getString(JF_ICON));
if (!TextUtils.isEmpty(Obj.getString(JF_BACKGROUND_IMAGE))) {
category.setImageUrl(Obj.getString(JF_BACKGROUND_IMAGE));
}
Log.d("URL1",""+Obj.getString(JF_TITLE));
categoryList.add(category);
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
categoryListView.setAdapter(new CategoryAdapter(getActivity(), mCallbacks, categoryList));
}
});
}catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (JSONException e) {
// TODO Auto-generated catch block
Error = e.getMessage();
e.printStackTrace();
} catch (NullPointerException e) {
// TODO: handle exception
Error = e.getMessage();
}
return null;
}
}
//! function for populate category list
private void initCategoryList() {
new getCategList().execute();
}
#Override
public void onConnectionEstablished(int code) {
if (code == CATEGORY_ACTION) {
initCategoryList();
}
}
#Override
public void onUserCanceled(int code) {
if (code == CATEGORY_ACTION) {
getActivity().finish();
}
}
//! catch json response from here
#Override
public void onSuccessResponse(String tag, String jsonString) {
//! do same parsing as done in initCategoryList()
}
//! detect response error here
#Override
public void onFailureResponse(String tag) {
}
//! callback interface listen by HomeActivity to detect user click on category
public static interface CategorySelectionCallbacks {
void onCategorySelected(String catID, String title);
}
}
This code for categoryAdapter.java (where i put the result of JSON to the list)
public class CategoryAdapter extends ArrayAdapter<Category> implements View.OnClickListener {
private final LayoutInflater inflater;
private final ArrayList<Category> categoryList;
private Activity activity;
private HomeFragment.CategorySelectionCallbacks mCallbacks;
private String dummyUrl = "http://www.howiwork.org";
AbsListView.LayoutParams params;
public CategoryAdapter(Activity activity, HomeFragment.CategorySelectionCallbacks mCallbacks, ArrayList<Category> categoryList) {
super(activity, R.layout.layout_category_list);
this.activity = activity;
this.inflater = LayoutInflater.from(activity.getApplicationContext());
this.categoryList = categoryList;
this.mCallbacks = mCallbacks;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder row;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_category_list, null);
row = new ViewHolder();
row.bannerImage = (ImageView) convertView.findViewById(R.id.catBannerImageView);
row.categoryImage = (ImageView) convertView.findViewById(R.id.catImageView);
row.categoryName = (TextView) convertView.findViewById(R.id.catNameTV);
} else {
row = (ViewHolder) convertView.getTag();
}
Category category = categoryList.get(position);
Picasso.with(activity).load(UtilMethods
.getDrawableFromFileName(activity,category.getIconUrl()))
.tag(category.getIconUrl())
.into(row.categoryImage);
row.categoryName.setText(category.getTitle());
Picasso.with(activity)
.load(UtilMethods.getDrawableFromFileName(activity,category.getImageUrl()))
.placeholder(R.drawable.img_banner_placeholder)
.tag(category.getIconUrl())
.fit()
.into(row.bannerImage);
row.bannerImage.setOnClickListener(this);
row.categoryImage.setTag(position);
row.categoryName.setTag(position);
row.bannerImage.setTag(position);
return convertView;
}
#Override
public int getCount() {
return categoryList.size();
}
#Override
public void onClick(View v) {
int position = Integer.parseInt(v.getTag().toString());
mCallbacks.onCategorySelected(categoryList.get(position).getId(),
categoryList.get(position).getTitle());
}
private static class ViewHolder {
public ImageView bannerImage;
public TextView categoryName;
public ImageView categoryImage;
}
}
Try this.
Picasso.with(activity).load(category.getIconUrl())
.into(row.categoryImage);
If it worked !. You Check the UtilMethods.getDrawableFromFileName() !!!
My application pulls data from a web service that generates different sections for each user. Then I am going to use these sections to create tabs using FragmentPagerAdapter.
I have used an Async task to pull data from the web service. However the overridden methods such as getCount() and getPageTitle() in the FragmentPagerAdapter executed prior to my asynctask and completes its job. How can I prevent this and generate dynamic number of tabs and their title name based on the data fetched from the web service?
In other words how can I create dynamic number of tabs and titles based on the data fetch from the web service
My Code for FragmentPagerAdapter as below. As you can see I have hard coded the amount of tabs as well as their title names.
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new SectionFragment();
Bundle args = new Bundle();
args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Camera".toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return "SECTION 4";
}
return null;
}
//setting the section title
private void setSectionTitle(){
}
//count the number of sections
private int countNumberofSections(){
int numberOfSection = 0;
return numberOfSection;
}
}
Then I have my Fragment code as below which has the the caller to the Async Task
public static class SectionFragment extends Fragment implements OnTaskCompleted {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private Slider adapter;
private ViewPager viewPager;
public static final String ARG_SECTION_NUMBER = "section_number";
Button thumbUpBut;
Button thumbDownBut;
Button captureButton;
ImageView genImage;
TextView genCaption;
private Camera mCamera;
private CameraPreview mPreview;
private static File mediaFile;
private ProgressDialog progress;
private static String imageSaveLocation;
private static String file_name_without_extension;
private ImageView imageView;
private Button uploadButton;
private Button cancelButton;
private Collection<Place> places = null;
private Collection<Happenings> events = null;
private Collection<General> general = null;
private ArrayList<String> sections;
public int getNumberOfPages(){
return sections.size();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
FeedRequest task = new FeedRequest(this);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
captureButton = (Button) rootView.findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
thumbUpBut = (Button) rootView.findViewById(R.id.thumbUp);
thumbUpBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressUp");
thumb("up");
}
});
thumbDownBut = (Button) rootView.findViewById(R.id.thumbDown);
thumbDownBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressDown");
thumb("down");
}
});
//allocating the activity one to the camera
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){
mCamera = getCameraInstance();
mPreview = new CameraPreview(this.getActivity(), mCamera);
FrameLayout preview = (FrameLayout)rootView.findViewById(R.id.camera_preview);
preview.addView(mPreview);
//hide buttons
thumbDownBut.setVisibility(rootView.INVISIBLE);
thumbUpBut.setVisibility(rootView.INVISIBLE);
}else{
thumbDownBut.setVisibility(rootView.VISIBLE);
thumbUpBut.setVisibility(rootView.VISIBLE);
captureButton.setVisibility(rootView.INVISIBLE);
}
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
return rootView;
}
//take photo function
private void takePhoto() {
//get coordinates of the location
UserLocation userLocation = new UserLocation();
userLocation.getUserLocation(getActivity());
coordinates[0] = userLocation.longitude;
coordinates[1] = userLocation.latitude;
PictureCallback pictureCB = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera cam) {
new SavePhotoAndMetadata().execute(data);
cam.startPreview();
}
};
mCamera.takePicture(null, null, pictureCB);
}
//get camera instance
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
//get the media out
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString());
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
file_name_without_extension = "IMG_" + timeStamp;
imageSaveLocation = mediaFile.toString();
return mediaFile;
}
//saving the image and metadata together
class SavePhotoAndMetadata extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... data) {
File picFile = getOutputMediaFile();
if (picFile == null) {
return null;
}
byte[] photoData = data[0];
try {
//save the image
FileOutputStream fos = new FileOutputStream(picFile);
fos.write(photoData);
fos.close();
} catch (FileNotFoundException e) {
e.getStackTrace();
} catch (IOException e) {
e.getStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progress = new ProgressDialog(getActivity());
progress.setMessage("Saving Picture..Please wait...");
progress.show();
}
#Override
protected void onPostExecute(String s) {
progress.dismiss();
imagePreviewDialog();
}
}
//save image metadata in async task
class SaveMetadataTask extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... params) {
serializeDeserialize.serializeData("This is for testing", file_name_without_extension, Double.toString(coordinates[0]), Double.toString(coordinates[1]), deviceId, deviceEmail);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void v) {
}
}
//image preview dialog and its functionality
private void imagePreviewDialog(){
//setting the bitmap
Bitmap bmp = BitmapFactory.decodeFile(mediaFile.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Image Preview");
builder.setCancelable(false);
LayoutInflater inflater = getActivity().getLayoutInflater();
ViewGroup vg = (ViewGroup)inflater.inflate(R.layout.sanp_preview_layout, null);
ImageView image = (ImageView) vg.findViewById(R.id.imageView);
image.setImageBitmap(rotateBitmap(bmp));
builder.setView(vg);
//buttons
builder.setPositiveButton("Upload",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(checkInternetConnection.haveNetworkConnection(sContext)){
//upload the image
uploadImage();
//save image metadata
new SaveMetadataTask().execute();
}else{
Toast.makeText(sContext, "Error! No internet connection detected. Image will be uploaded on an active internet connection", Toast.LENGTH_LONG).show();
new SaveMetadataTask().execute();
}
}
});
builder.setNegativeButton("Discard",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
discardImage(mediaFile.toString());
dialog.dismiss();
}
});
builder.show();
}
private Bitmap rotateBitmap(Bitmap image){
int width=image.getHeight();
int height=image.getWidth();
Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig());
for (int y=width-1;y>=0;y--)
for(int x=0;x<height;x++)
srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y));
return srcBitmap;
}
//device email
private String getDeviceEmail(){
AccountManager accountManager = AccountManager.get(sContext);
Account[] account = accountManager.getAccountsByType("com.google");
//device email
for(Account accLoop : account){
deviceEmail = accLoop.name;
}
return deviceEmail;
}
//upload image to the server
private void uploadImage(){
//save metadata
//call upload service
Intent intent = new Intent(sContext, HttpUploader.class);
Bundle loc = new Bundle();
loc.putDoubleArray("ss", coordinates);
intent.putExtra("url", PHOTO_UPLOAD);
intent.putExtra("paths", mediaFile.toString());
intent.putExtra("deviceid", deviceId);
intent.putExtra("deviceemail", getDeviceEmail());
intent.putExtra("posttext", "This is for testing");
intent.putExtra("filename", file_name_without_extension);
intent.putExtra("geo", loc);
sContext.startService(intent);
Toast.makeText(getActivity(), "Your image is being uploaded", Toast.LENGTH_LONG).show();
}
//discard image when the discard button is pressed
private void discardImage(String imagePath){
File file = new File(imagePath);
try{
file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
#Override
public void onTaskCompleted(boolean status, String message) {
// TODO Auto-generated method stub
Log.e("onTaskCompleted", "success" + status);
if (message == "tumb UP success") {
thumbUpBut.setSelected(true);
thumbDownBut.setSelected(false);
Log.e("tumb", "tumb");
} else if (message == "tumb DOWN success") {
thumbDownBut.setSelected(true);
thumbUpBut.setSelected(false);
Log.e("tumb", "tumb");
}
}
//listener for fetching main objects
#Override
public void onFeedCompleted(ArrayList<Posts> postArray, Multimap<String, Object> multiMap) {
// TODO Auto-generated method stub
numberOfPages = postArray.size();
adapter = new Slider(getActivity(), postArray, getContext());
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(postArray.size());
//saving the keyset
Set<String> keys = multiMap.keySet();
sections = new ArrayList<String>();
//sorting the categories and creating the category list
for(String key:keys){
//getting category list
if(!sections.contains(keys)){
sections.add(key);
}
//sorting categories
if(key.equals("Place")){
places.add((Place) multiMap.get(key));
}else if(key.equals("Events")){
events.add((Happenings) multiMap.get(key));
}else if(key.equals("General")){
general.add((General) multiMap.get(key));
}
}
}
//adding the pages to the adaptor dynamically
public void addPagesDynamically(){
}
}
//create the parent directory
private void createParentDiectory(){
File dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap");
if(!(dir.exists() && dir.isDirectory())) {
dir.mkdirs();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_post:
openPost();
return true;
case R.id.action_settings:
// openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void openPost() {
/*
Intent i = new Intent(getApplicationContext(), PhotoActivity.class);
startActivity(i);
*/
}
public static void thumb(String type) {
SectionFragment d = new SectionFragment();
PostThumb task = new PostThumb(type, d);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
//broadcast receiver for picture upload
public class MyWebRequestReceiver extends BroadcastReceiver {
public static final String PROCESS_RESPONSE = "asia.ceynet.intent.action.PROCESS_RESPONSE";
#Override
public void onReceive(Context context, Intent intent) {
//String responseString = intent.getStringExtra(HttpUploader.RESPONSE_STRING);
String reponseMessage = intent.getStringExtra(HttpUploader.RESPONSE_MESSAGE);
String responseStatus = intent.getStringExtra(HttpUploader.RESPONSE_STATUS);
String file_to_be_deleted = intent.getStringExtra(HttpUploader.FILE_NAME_WITHOUT_EXTENSION);
Toast.makeText(getApplicationContext(), reponseMessage + " - " + file_to_be_deleted + ".jpg", Toast.LENGTH_LONG).show();
//if uploaded successfully delete or image and metadata
if(responseStatus.equals("true")){
File temp_image_dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".jpg");
File metadata_file = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".ser");
try{
temp_image_dir.delete();
metadata_file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
}
}
When you finnish pulling the async data, provide the adapter with the new data and call .notifyDataSetChanged() on that adapter instance and the framework will update the pages and count by itself.
If you wish a more detailed explanation post your FragmentPagerAdapter implementation.
First of all, let me apologize if I'm not making myself clear enough because this is one of my first participation(s) here. But I'll be always here to answer queries related to this answer and clear any confusions arose by my statements.
Since you're using fragments, so I'm assuming you must have included your fragments inside an activity (lets say MainActivity.java).
What you need, can be done inside that activity containing fragment.
Here is the example code of onCreate method inside the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
//Instance of viewpager included inside activity_main.xml
viewPager = (ViewPager) findViewById(R.id.vpMain);
SectionsPagerAdapter adapter = new SectionsPagerAdapter (fragmentManager);
//Adding some fragments right from the beginning, you could ignore it if not needed.
addFragments();
//This `OnPageChangeListener` will do the trick for you.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//Show the title of fragment
Toast.makeText(MainActivity.this, adapter.screens.get(position), Toast.LENGTH_SHORT).show();
//If fragment being loaded is later than the first one,
// then add one more fragment after the last fragment to the adapter.
// integer currentPosition is declared as a field, outside onCreate method and initially set to 0.
if(position>currentPosition){
currentPosition+=1;
adapter.addFragment(new SectionFragment(), "Fragment"+String.valueOf(position+3));
adapter.notifyDataSetChanged();
}else{
currentPosition--;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
} // onCreate ends here.
Create this method inside your MainActivity (just to add 3 fragments to give your application a head-start.
private void addFragments(){
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
}
Then modify your SectionsPagerAdapter's getItem and getCount methods as below:
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return screens.get(position);
}
#Override
public int getCount() {
return screens.size();
}
//This method will dynamically add a fragment each time it is called.
public void addFragment(Fragment fragment) {
screens.add(fragment);
}
Now, no work related to "adding new fragment to the list" needs to be done inside your SectionFragment class.