Good day guys,
I successfully populated my custom-listview-layout in my activity,
but the problem is I can't get all the value of populated EditText in my listview, please help me what approach should I do,
thanks
Picture Adapter.java
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row = convertView;
final dataHandler handler;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate( R.layout.row_layout,parent, false);
handler = new dataHandler();
handler.pictures = (ImageView) row.findViewById(R.id.pictures);
handler.name = (TextView) row.findViewById(R.id.picturename);
handler.price= (EditText) row.findViewById(R.id.price);
handler.add = (Button) row.findViewById(R.id.btnplus);
handler.minus = (Button) row.findViewById(R.id.btnminus);
row.setTag(handler);
}else{
handler = (dataHandler) row.getTag();
}
PSP psp;
psp =(PSP) this.getItem(position);
Picasso.with(getContext()).load(psp.getPicture()).resize(200, 155).into(handler.pictures);
handler.name.setText(psp.getName());
handler.price.setText(psp.getPrice());
return row;
}
MainActivity.java
PictureAdapter adapter;
listView = (ListView) findViewById(R.id.ls);
adapter = new PictureAdapter(this,R.layout.row_layout);
listView.setAdapter(adapter);
try {
JSONArray users = response.getJSONArray("user");
for (int x = 0; x <= users.length()-1; x++) {
JSONObject user = users.getJSONObject(x);
PSP psp = new PSP(imageUri+user.getString("image")+".png",user.getString("username"),"0");
adapter.add(psp);
}
} catch (JSONException e) {
e.printStackTrace();
}
PSP.java
public class PSP
{
private String picture;
private String name;
private String price;
public String getPicture() {
return picture;
}
public PSP(String picture, String name, String price){
this.setPicture(picture);
this.setName(name);
this.setPrice(price);
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
row_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="80dp"
android:background="#000000">
<ImageView
android:id="#+id/pictures"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="#+id/picturename"
android:layout_width="115dp"
android:layout_height="75dp"
android:layout_toRightOf="#+id/pictures"
android:text="Kim Domingo"
android:gravity="center"
android:textColor="#FFFFFF"
/>
<Button
android:id="#+id/btnplus"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center"
android:text="+"
android:textSize="50px"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/picturename"
android:layout_toEndOf="#+id/picturename"
/>
<EditText
android:id="#+id/price"
android:layout_width="50dp"
android:layout_height="50dp"
android:focusable="false"
android:textColor="#FFFFFF"
android:inputType="number"
android:gravity="center"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/btnplus"
android:layout_toEndOf="#+id/btnplus" />
<Button
android:id="#+id/btnminus"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="center"
android:text="-"
android:textSize="50px"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/price"
android:layout_toEndOf="#+id/price" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#FFFFFF"
android:layout_below="#+id/pictures"
android:id="#+id/editText"></View>
I created same before like this
You can use the HashMap map = new HashMap<>(); for what item user click. I assume that you use two button click are available in adapter class if not then add it.
Step 1 First Declare the HashMap map = new HashMap<>(); in adapter.
Step 2 Then put value in HashMap map.put("key","value"); This code put in both plus and minus button click event.
Step 3 Call ShowHashMapValue(); method below to the map.put("key","value"); for see the HashMap values check logcat for that.
Compare this adapter code for understand easily if any problem just comment below.
ListAdapter.java
public class ListAdapter extends BaseAdapter {
public ArrayList<Integer> quantity = new ArrayList<Integer>();
public ArrayList<Integer> price = new ArrayList<Integer>();
private String[] listViewItems, prices, static_price;
TypedArray images;
View row = null;
static String get_price, get_quntity;
int g_quntity, g_price, g_minus;
private Context context;
CustomButtonListener customButtonListener;
static HashMap<String, String> map = new HashMap<>();
public ListAdapter(Context context, String[] listViewItems, TypedArray images, String[] prices) {
this.context = context;
this.listViewItems = listViewItems;
this.images = images;
this.prices = prices;
for (int i = 0; i < listViewItems.length; i++) {
quantity.add(0);
}
}
public void setCustomButtonListener(CustomButtonListener customButtonListner) {
this.customButtonListener = customButtonListner;
}
#Override
public int getCount() {
return listViewItems.length;
}
#Override
public String getItem(int position) {
return listViewItems[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListViewHolder listViewHolder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.activity_custom_listview, parent, false);
listViewHolder = new ListViewHolder();
listViewHolder.tvProductName = (TextView) row.findViewById(R.id.tvProductName);
listViewHolder.ivProduct = (ImageView) row.findViewById(R.id.ivproduct);
listViewHolder.tvPrices = (TextView) row.findViewById(R.id.tvProductPrice);
listViewHolder.btnPlus = (ImageButton) row.findViewById(R.id.ib_addnew);
listViewHolder.edTextQuantity = (EditText) row.findViewById(R.id.editTextQuantity);
listViewHolder.btnMinus = (ImageButton) row.findViewById(R.id.ib_remove);
static_price = context.getResources().getStringArray(R.array.Price);
row.setTag(listViewHolder);
} else {
row = convertView;
listViewHolder = (ListViewHolder) convertView.getTag();
}
listViewHolder.ivProduct.setImageResource(images.getResourceId(position, -1));
listViewHolder.edTextQuantity.setText(quantity.get(position) + "");
listViewHolder.tvProductName.setText(listViewItems[position]);
listViewHolder.tvPrices.setText(prices[position]);
listViewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, 1);
quantity.set(position, quantity.get(position) + 1);
//price.set(position, price.get(position) + 1);
row.getTag(position);
get_price = listViewHolder.tvPrices.getText().toString();
g_price = Integer.valueOf(static_price[position]);
get_quntity = listViewHolder.edTextQuantity.getText().toString();
g_quntity = Integer.valueOf(get_quntity);
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
// Log.d("A ", "" + a);
// Toast.makeText(context, "A" + a, Toast.LENGTH_LONG).show();
// Log.d("Position ", "" + position);
// System.out.println(+position + " Values " + map.values());
listViewHolder.tvPrices.getTag();
listViewHolder.tvPrices.setText("" + g_price * g_quntity);
ShowHashMapValue();
}
}
});
listViewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, -1);
if (quantity.get(position) > 0)
quantity.set(position, quantity.get(position) - 1);
get_price = listViewHolder.tvPrices.getText().toString();
g_minus = Integer.valueOf(get_price);
g_price = Integer.valueOf(static_price[position]);
int minus = g_minus - g_price;
if (minus >= g_price) {
listViewHolder.tvPrices.setText("" + minus);
}
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
ShowHashMapValue();
}
}
});
return row;
}
private void ShowHashMapValue() {
/**
* get the Set Of keys from HashMap
*/
Set setOfKeys = map.keySet();
/**
* get the Iterator instance from Set
*/
Iterator iterator = setOfKeys.iterator();
/**
* Loop the iterator until we reach the last element of the HashMap
*/
while (iterator.hasNext()) {
/**
* next() method returns the next key from Iterator instance.
* return type of next() method is Object so we need to do DownCasting to String
*/
String key = (String) iterator.next();
/**
* once we know the 'key', we can get the value from the HashMap
* by calling get() method
*/
String value = map.get(key);
System.out.println("Key: " + key + ", Value: " + value);
}
}
}
So so here is logic. You need to declare a boolean in PSP. by default set it to false.
Now when + button will be triggered you need to set that boolean check to true
then in your set price create this logic.
public String getPrice() {
if(check==true){
price++;
}
else{
price--;
}
return price;
}
If i correctly understand you then this surely will help you. Good Luck!
Related
I have a listview that when I change the value of one item (count) with click on plus button, Everything is fine as long as the user do scroll down and show more items
And we see that on each page of the scroll has changed a value of item!!!
idont kNow why everything seems fine!!
public class MyAdapter extends BaseAdapter {
private String[] from;
ArrayList <HashMap<String, Object>> BuyList ;
private int[] to;
private Context context;
private ArrayList<HashMap<String, Object>> data ;
private ArrayList<HashMap<String, Object>> selecteddata;
private ArrayList<HashMap<String, Object>> fdata ;
private ImageView pay,more;
private EditText search;
private String user_mobile;
private TextView buy_toolbar_count;
private Holder holder;
// private HashMap<String, Object> hm;
public MyAdapter( Context context, ArrayList<HashMap<String, Object>> data,
ArrayList<HashMap<String, Object>> selecteddata , String[] from, int[] to, ArrayList Bylist,
ImageView pay, ImageView more, String user_mobile, TextView buy_count_toolbar, EditText search) {
this.data = data;
this.selecteddata = selecteddata;
this.fdata = new ArrayList<>(selecteddata);
this.context = context;
this.from = from;
this.to = to;
this.BuyList = Bylist;
this.pay = pay;
this.more = more;
this.search = search;
this.user_mobile = user_mobile;
this.buy_toolbar_count = buy_count_toolbar;
}
public void filter(String s, ImageView img) {
HashMap<String, Object> wp = new HashMap<>();
if (!s.equals("")) {
fdata.clear();
for (int i = 0 ;i<data.size();i++) {
wp = data.get(i);
// Log.i("mosi",wp.get("name").toString() + " wp ");
if (wp.get("name").toString().toLowerCase().contains(s)) {
fdata.add(wp);
}
}
}
else {
fdata = new ArrayList<>(selecteddata);
}
notifyDataSetChanged();
}
public class Holder
{
ImageView g_img;
ImageView plus;
ImageView mines;
TextView g_name;
TextView g_price;
TextView g_off;
TextView count;
TextView f_range;
TextView sum;
TextView temp2;
}
#Override
public int getCount() {
return fdata.size();
}
#Override
public HashMap<String, Object> getItem(int i) {
return fdata.get(i);
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Typeface font_titr = Typeface.createFromAsset(context.getAssets(), "fonts/titr.TTF");
final HashMap<String, Object> hm = fdata.get(position);
if (convertView == null ) {
holder = new Holder();
convertView = LayoutInflater.from(context).
inflate(R.layout.my_row_layout2, parent, false);
holder.g_img = (ImageView) convertView.findViewById(R.id.f_img);
holder.g_name = (TextView) convertView.findViewById(R.id.f_name);
holder.g_price = (TextView) convertView.findViewById(R.id.f_price);
holder.g_off = (TextView) convertView.findViewById(R.id.f_off);
holder.count = (TextView) convertView.findViewById(R.id.f_count);
holder.f_range = (TextView) convertView.findViewById(R.id.f_kilo);
holder.plus = (ImageView) convertView.findViewById(R.id.plus_id_btn);
holder.mines = (ImageView) convertView.findViewById(R.id.mines_id_btn);
holder.sum = (TextView) convertView.findViewById(R.id.count_sum_id);
holder.temp2 = (TextView) convertView.findViewById(R.id.txt2);
//Date currentTime = Calendar.getInstance().getTime();
convertView.setTag(holder);
// Log.i("mosi",convertView.getTag() + " tagfffff " + hm.get("convertview"));
hm.put("convertview", "1");
}
else
{
holder = (Holder) convertView.getTag();
// Log.i("mosi",convertView.getTag() + " tag " + hm.get("convertview"));
}
final View tempview = convertView;
// set font++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
holder.g_price.setTypeface(font_titr, Typeface.NORMAL);
holder.g_name.setTypeface(font_titr, Typeface.BOLD);
holder.g_off.setTypeface(font_titr, Typeface.NORMAL);
holder.count.setTypeface(font_titr, Typeface.NORMAL);
holder.sum.setTypeface(font_titr, Typeface.NORMAL);
holder.temp2.setTypeface(font_titr, Typeface.NORMAL);
//----------------------------------------------------------------------------------------
// Set pre count and sum
holder.sum.setText(" میلغ کل : " + hm.get("sum").toString() + " تومان ");
holder.count.setText(hm.get("count").toString());
final String oldprice = hm.get("price").toString();
holder.g_off.setText(hm.get("off").toString());
holder.g_name.setText(hm.get("disc").toString());
holder.f_range.setText(hm.get("f_range").toString());
final float f=
(Float.valueOf(oldprice)*
Float.valueOf(holder.g_off.getText().toString()))/100;
// holder.g_price.setText(" قیمت : "+ DtoS((Float.valueOf(oldprice.toString()))-f)+" تومان ");
holder.g_price.setText(" قیمت : "+ oldprice +" تومان ");
File imageFile = new File(hm.get("image").toString());
if(imageFile.exists()){
holder.g_img.setImageBitmap(BitmapFactory.decodeFile(imageFile.getAbsolutePath()));
}
else
holder.g_img.setImageResource(R.drawable.coming_soon);
holder.plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
change_count(holder, hm, "p", tempview, ChangeType.DtoS((Float.valueOf(oldprice.toString())) - f), position);
}
});
holder.mines.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
change_count(holder, hm, "m", tempview , ChangeType.DtoS((Float.valueOf(oldprice.toString()))-f), position);
}
});
// Button Pay && More
pay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (BuyList.size() > 0) {
Intent intent = new Intent(context, Payment_act.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("data", BuyList);
intent.putExtra("all_data", data);
intent.putExtra("mobile", user_mobile);
view.getContext().startActivity(intent);
//
} else {
Toast.makeText(context, "سبد خرید شما خالی است", Toast.LENGTH_LONG).show();
}
}
});
more.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, Choose_act.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("blist", BuyList);
intent.putExtra("data", data);
intent.putExtra("mobile", user_mobile);
view.getContext().startActivity(intent);
// ((Activity)context).finish();
}
});
// Search -------------------------------------------------------------------
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence s, int i, int i1, int i2) {
// Log.i("mosi", s+" --- s ***");
// filter(s.toString(), holder.g_img);
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return convertView;
}
// template
// Onclick for mines and plus Button
//#Override
public void change_count(final Holder holder1, HashMap<String, Object> hm_addtolist, String tag, View c_view, String oldprice, int position) {
// Log.i("mosi", position+" position on list ");
String is_pack = hm_addtolist.get("is_pack").toString();
ChangeType ch = new ChangeType();
double temp1 = 0;
double p_with_off = 0;
holder = (Holder) c_view.getTag();
String off = hm_addtolist.get("off").toString();
String num_sum = "0";
if (ch.stringToDouble(off)>0)
{
p_with_off = ch.stringToDouble(hm_addtolist.get("price_with_off").toString());
}
else
p_with_off = ch.stringToDouble(oldprice.toString());
holder.count= (TextView) c_view.findViewById(R.id.f_count);
holder.sum = (TextView) c_view.findViewById(R.id.count_sum_id);
if (!holder.count.getText().toString().equals("") && holder.count!= null)
temp1 = ch.stringToDouble(holder.count.getText().toString());
//my_alert("", temp1+"");
if (tag.equals("p")) {
if (is_pack.equals("1"))
temp1 = temp1 + 1;
else
temp1 = temp1 + 0.5;
// Log.i("mosi", " ::: set 2 !!!!");
holder.count.setText(DtoS(temp1));
num_sum = String.format("%d", (long)(temp1 * p_with_off));
holder.sum.setText(" میلغ کل : " + num_sum + " تومان ");
} else if (tag.equals("m")) {
if (is_pack.equals("1")) {
if (temp1 > 1) {
temp1 = (temp1 - 1);
holder.count.setText(DtoS(temp1));
num_sum = String.format("%d", (long) (temp1 * p_with_off));
holder.sum.setText(" میلغ کل : " + num_sum + " تومان ");
} else {
holder.count.setText("0");
holder.sum.setText("مبلغ کل : 0 تومان");
num_sum = "0";
BuyList.remove(hm_addtolist);
notifyDataSetChanged();
buy_toolbar_count.setText(String.valueOf(BuyList.size()));
}
}
else {
if (temp1 > 0.5) {
temp1 = (temp1 - 0.5);
holder.count.setText(DtoS(temp1));
num_sum = String.format("%d", (long) (temp1 * p_with_off));
holder.sum.setText(" میلغ کل : " + num_sum + " تومان ");
} else {
holder.count.setText("0");
holder.sum.setText("مبلغ کل : 0 تومان");
num_sum = "0";
hm_addtolist.put("count","0");
hm_addtolist.put("sum","0");
BuyList.remove(hm_addtolist);
notifyDataSetChanged();
buy_toolbar_count.setText(String.valueOf(BuyList.size()));
}
}
}
//}
if (!num_sum.equals("0")) {
hm_addtolist.put("sum", num_sum);
hm_addtolist.put("count", holder.count.getText().toString());
boolean check = false;
for (int i = 0; i < BuyList.size(); i++) {
if (BuyList.get(i).get("name").toString().equals(hm_addtolist.get("name").toString())) {
check = true;
HashMap<String, Object> temp_updatelist = BuyList.get(i);
temp_updatelist.put("sum", num_sum);
temp_updatelist.put("count", holder.count.getText().toString());
// BuyList.add(temp_updatelist);
// Log.i("mosi", "add count "+i+"");
// Toast.makeText(context, "ok", Toast.LENGTH_SHORT);
notifyDataSetChanged();
}
}
if (!check) {
// Log.i("mosi", "add count to :: "+hm_addtolist.get("name")+"");
BuyList.add(hm_addtolist);
buy_toolbar_count.setText(String.valueOf(BuyList.size()));
notifyDataSetChanged();
}
}
notifyDataSetChanged();
// Log.i("mosi", BuyList.toString());
// clearbug( c_view);
}
}
make list on activity
I have a listview that when I change the value of one item (count) with click on plus button, Everything is fine as long as the user do scroll down and show more items
And we see that on each page of the scroll has changed a value of item!!!
idont kNow why everything seems fine!!
private void setlist() {
ArrayList<HashMap<String, Object>> selected_data = new ArrayList<>();
for (int i = 0; i < all_data.size(); i++) {
if (all_data.get(i).get("type").toString().equals(mtag)) {
HashMap<String, Object> t = all_data.get(i);
selected_data.add(t);
}
}
//Log.i("mosi",selected_data.toString());
EditText search = (EditText) findViewById(R.id.et_search_id);
ImageView pay = (ImageView) findViewById(R.id.btn_pay_firstpage);
ImageView more = (ImageView) findViewById(R.id.btn_more_firstpage);
String[] from = {"image", "name", "price", "off"};
int[] to = {R.id.f_img, R.id.f_name, R.id.f_price, R.id.f_off};
final MyAdapter adb = new MyAdapter(getBaseContext(), all_data, selected_data, from, to, BuyList, pay, more, user_mobile, buyCount_toolbar, search);
lv.setAdapter(adb);
}
I have a listview that when I change the value of one item (count) with click on plus button, Everything is fine as long as the user do scroll down and show more items
And we see that on each page of the scroll has changed a value of item!!!
idont kNow why everything seems fine!!
its my activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
android:background="#drawable/main_background_theme">
<include
android:id="#+id/mytoolbar"
layout="#layout/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"/>
<include
android:id="#+id/app_message"
layout="#layout/message"
android:layout_height="30dp"
android:layout_width="match_parent"
android:layout_below="#+id/mytoolbar"/>
<include
android:id="#+id/searchbox_id"
layout="#layout/searchbox"
android:layout_height="40sp"
android:layout_width="match_parent"
android:layout_below="#+id/app_message"
android:visibility="invisible"/>
<android.support.v4.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/searchbox_id"
android:id="#+id/FirstPage_id">
<RelativeLayout
android:id="#+id/rv_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainLayoutActivity">
<ListView
android:id="#+id/my_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/listDivader"
android:dividerHeight="1dp"
android:paddingBottom="?attr/actionBarSize" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignBottom="#id/my_listview"
android:background="#color/toolbar_back"
android:orientation="horizontal">
<ImageView
android:id="#+id/btn_pay_firstpage"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="50"
android:paddingLeft="10sp"
android:src="#drawable/btn_pay" />
<ImageView
android:id="#+id/btn_more_firstpage"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="50"
android:paddingLeft="10sp"
android:src="#drawable/btn_more" />
</LinearLayout>
</RelativeLayout>
<fragment
android:layout_width="180dp"
android:layout_height="match_parent"
android:id="#+id/drawer_fragment"
android:layout_gravity="start"
android:layout="#layout/drawer_fragment_layout"
tools:layout="#layout/drawer_fragment_layout"
android:name="com.com.seyedi89gmail.sm.zanco.Drawer_fragment">
</fragment>
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
Remove notifyDataSetChanged from if-else conditions, May this will work
public void filter(String s, ImageView img) {
HashMap<String, Object> wp = new HashMap<>();
if (!s.equals("")) {
fdata.clear();
for (int i = 0 ;i<data.size();i++) {
wp = data.get(i);
if (wp.get("name").toString().toLowerCase().contains(s)) {
fdata.add(wp);
//notifyDataSetChanged();
}
}
}
else {
fdata = new ArrayList<>(selecteddata);
//notifyDataSetChanged();
}
notifyDataSetChanged();
}
you can use NestedScrollview outside the listview and stop the scrolling of listview by using this: smoothScrollBy(0, 0);
I have an activity which generates a scrollable list (let's say a column) of programmatically created buttons from a List which is the result of an sqlite table read and my problem is that as the List is growing (and so the number of buttons) the initial painting of the screen is becoming slow (at the moment is taking 3 seconds with 50 buttons to draw) so I'm looking for a solution to this.
At first I thought of using a thread (runnable, handler or whatever is best), let's say creating a new thread inside the For which iterates over the list but it's not working (or at least I'm not being able to make it to work) so my question is the next:
Starting from a List<> which is the most appropiate way to create a big set of scrollable buttons so users doesn't have such delay when accesing the screen.
Paginating could be an option, but I'd like to know about other possibilities first and leave that as a last resource.
Thanks, and below is my code.
public static void createButtons(LinearLayout llContainer,
List<TestType> TestTypes, List<Test> Tests,
int buttonFontSize) {
Context oContext = llContainer.getContext();
String strTheme = TMAppearance.getThemeFromPreferences(oContext);
testMe = ((ApplicationConfiguration)oContext.getApplicationContext());
int callerActivity = TestTypes!=null ? 2 : 1;
if (TestTypes!=null || Tests!=null) {
int lCols = strTheme.equals(testMe.theme_vivid) ? 1 : 2;
//int sourceElementIndex = 0;
int originListSize = calculateOriginalListSize(callerActivity, TestTypes, Tests);
int lRows = (int) Math.ceil((double)originListSize/lCols);
List<String> aStartColors = TMUtils_ThemeVivid.generateStartColorArray(lRows, oContext);
List<String> aEndColors = TMUtils_ThemeVivid.generateEndColorArray(lRows, oContext);
for (i = 0; i < lRows; i++) {
LinearLayout outerButtonLayout = generateOuterButtonLayout(oContext);
for (j = 0; j < lCols; j++) {
final Thread r = new Thread() {
public void run() {
LinearLayout innerButtonLayout = generateInnerButtonLayout(oContext);
outerButtonLayout.addView(innerButtonLayout, j);
if (sourceElementIndex<originListSize){
final TMButton oButton = new TMButton(oContext);
if (callerActivity==1) { //testMenu
setTestMenuButtonSettings(oButton, sourceElementIndex, Tests);
} else {
if (callerActivity==2) { //testTypeMenu
setTestTypeMenuButtonSettings(oButton, sourceElementIndex, TestTypes);
}
}
if (strTheme.equals(testMe.theme_vivid)){
oButton.fontSize = buttonFontSize;
oButton.gradientStartColor = aStartColors.get(i);
oButton.gradientEndColor = aEndColors.get(i);
}else{
if (strTheme.equals(testMe.theme_purple)){
oButton.gradientStartColor = testMe.btnStartColor_purple;
oButton.gradientEndColor = testMe.btnEndColor_purple;
}
}
configureButton(oButton, callerActivity);
oButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Context oContext = v.getContext();
TMButton oButton = (TMButton) v;
int callerActivity = Integer.valueOf(v.getTag().toString().split("#")[0]);
String sourceId = String.valueOf(v.getTag().toString().split("#")[1]);
if(event.getAction() == MotionEvent.ACTION_DOWN) { //pressed
setButtonPressed(oButton);
TMSound.playButtonSound(oContext);
} else if (event.getAction() == MotionEvent.ACTION_UP) { //released
setButtonReleased(oButton);
startTargetActivity(callerActivity, sourceId, oContext);
}
return true;
}
});
TMAppearance.doButtonAnimation(oContext, oButton, i);
innerButtonLayout.addView(oButton);
sourceElementIndex++;
}
}
};
r.run();
}
llContainer.addView(outerButtonLayout);
}
}
}
0X0nosugar is correct. A RecycleView will provide better performance, but many beginners have more difficulty implementing it and with only 50 buttons performance shouldn't really be an issue. And although I generally like to abide by the rule 'Use the best available solution' I think it is still appropriate to learn how to implement the ListView. So...
You will need to create a custom adapter:
public class MyListDataAdapter extends ArrayAdapter<MyListData> {
private static final String TAG = "MyListDataAdapter";
public MyListDataAdapter(Context context, ArrayList<MyListData> data) {
super(context, 0, data);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
final MyListData data = getItem(position);
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.edit_list_item, parent, false);
}
// Add a TextView if you need one
final TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
Button btnEditTicketHolder = (Button) convertView.findViewById(R.id.btnEdit);
btnEditTicketHolder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
long userId = data.getUserId();
String fName = data.getFirstName();
Intent intent = new Intent(getContext(), EditActivity.class);
intent.putExtra("userId", userId);
intent.putExtra("fName", fName);
getContext().startActivity(intent);
}
});
String name = data.getFirstName();
tvName.setText(name);
return convertView;
}
}
Now you need your MyListData class to hold the data:
public class MyListData {
// Add more as you need
private long userId;
private String firstName;
public MyListData(){
}
public void setFirstName(String name){ this.firstName = name; }
public void setUserId(long id){ this.userId = id; }
public String getFirstName(){ return this.firstName; }
public long getUserId(){ return this.userId; }
}
Your custom ListView layout could look something like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
<TextView
android:id="#+id/tvName"
android:text="With Whom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
>
<Button
android:id="#+id/btnEdit"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:text="Edit"
android:backgroundTint="#color/colorAccent"
android:focusable="false"
/>
</LinearLayout>
</RelativeLayout>
In your Activity (eg. in the onCreate() method) where the ListView you will need to populate the data for the ListView. This should not be done on the UI Thread
ArrayList<MyListData> arrayListData = new ArrayList<MyListData>();
MyListDataAdapter adapter = new MyListDataAdapter(this, arrayListData);
for (MyListData g : result) {
adapter.add(g);
}
mLstMy.setAdapter(adapter);
Also in the activity where the ListView is to be maintained set up some onClick event handlers if you need them:
(I find that one of the small advantages of the ListView is that the onClick event is easier it implement than in the RecycleView)
mMyLst = (ListView) findViewById(lstMy);
mMyLst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long l) {
MyListData data = (MyListData) parent.getItemAtPosition(position);
selectedName = data.getName();
Intent intent = new Intent(ShowListDataActivity.this, MainActivity.class);
startActivity(intent);
}
});
mMyLst.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
MyListData data = (MyistData) adapterView.getItemAtPosition(i);
selectedName = data.getFirstName();
selectedTicketPosition = i;
// removeValue is my own method for removing an entry from the
// list MyListData and then call adapter.notifyDataSetChanged();
removeValue(i);
return true;
}
});
More than one value is received but when I am parsing the JSON into Android, it is only showing the first value.
Here is the JsonNew.php file:
require "index.php";
$user_shopID = $_POST["UniqueKey"] ;
$sql_query="Select * from products where ShopID like '$user_shopID';";
$result = mysqli_query($con, $sql_query);
$response = array();
while ($row = mysqli_fetch_array($result))
{
array_push($response,array("ProductID"=>$row[0],"Product Name"=>$row[1], "Buying Price"=>$row[3], "Selling Price"=>$row[4]));
}
echo json_encode(array("server_response"=>$response));
mysqli_close($con);
This is the ContactAdapters.java:
public class ContactAdapter extends ArrayAdapter {
List list = new ArrayList();
public ContactAdapter(#NonNull Context context, #LayoutRes int resource) {
super(context, resource);
}
public void add(Contacts object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Nullable
#Override
public Object getItem(int position) {
return list.get(position);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View row;
row = convertView;
ContactHolder contactHolder;
if (row == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout, parent, false);
contactHolder = new ContactHolder();
contactHolder.tx_id = (TextView) row.findViewById(R.id.id);
contactHolder.tx_name = (TextView) row.findViewById(R.id.name);
contactHolder.tx_buy = (TextView) row.findViewById(R.id.buy);
contactHolder.tx_sell = (TextView) row.findViewById(R.id.sell);
row.setTag(contactHolder);
} else {
contactHolder = (ContactHolder) row.getTag();
}
Contacts contacts = (Contacts) this.getItem(position);
contactHolder.tx_id.setText(contacts.getId());
contactHolder.tx_name.setText(contacts.getName());
contactHolder.tx_buy.setText(contacts.getBuy());
contactHolder.tx_sell.setText(contacts.getSell());
return row;
}
static class ContactHolder {
TextView tx_id, tx_name, tx_buy, tx_sell;
}
}
And this the row_layout.xml
android:layout_width="match_parent"
android:layout_height="75dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/id"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:text="TextView"
android:gravity="center"
android:textColor="#000000"
android:layout_below="#+id/textView13" />
<TextView
android:id="#+id/name"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/id"
android:text="TextView"
android:gravity="center"
android:textColor="#000000"
android:layout_below="#+id/textView14" />
<TextView
android:id="#+id/buy"
android:layout_width="100dp"
android:layout_height="match_parent"
android:text="TextView"
android:gravity="center"
android:textColor="#000000"
android:layout_toRightOf="#+id/name"
android:layout_toEndOf="#+id/name"
android:layout_alignTop="#+id/name" />
<TextView
android:id="#+id/sell"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/buy"
android:text="TextView"
android:gravity="center"
android:textColor="#000000"
android:layout_alignTop="#+id/buy"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
Here is DisplayProductsListview.java
listview = (ListView) findViewById(R.id.listview);
contactAdapter = new ContactAdapter(this,R.layout.row_layout);
listview.setAdapter(contactAdapter);
json_string = getIntent().getExtras().getString("json_data");
try {
jsonObject = new JSONObject(json_string);
jsonArray = jsonObject.getJSONArray("server_response");
int count=0;
String id, name, buy, sell;
while (count<jsonObject.length()){
JSONObject JO = jsonArray.getJSONObject(count);
id = JO.getString("ProductID");
name = JO.getString("Product Name");
buy = JO.getString("Buying Price");
sell = JO.getString("Selling Price");
Contacts contacts = new Contacts(id,name,buy,sell);
contactAdapter.add(contacts);
count++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Here is the Contacts.java
private String id, name, buy, sell;
public Contacts(String id, String name, String buy, String sell){
this.setId(id);
this.setName(name);
this.setBuy(buy);
this.setSell(sell);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBuy() {
return buy;
}
public void setBuy(String buy) {
this.buy = buy;
}
public String getSell() {
return sell;
}
public void setSell(String sell) {
this.sell = sell;
}
}
When I am getting the JSON datas from the server, they are coming perfectly, but when I am making them display in a list view those datas are not coming. Only the first data and his values are coming into the list view.
Here are the Screenshots:
Here you will See what is actually happening with me
In the contactAdapter class you have to create a ArrayList.
ArrayList<Contact> arrayList = new ArrayList<>();
Somewhat you have to do like this.
change this function
while (count<jsonArray.length()){
JSONObject JO = jsonArray.getJSONObject(count);
id = JO.getString("ProductID");
name = JO.getString("Product Name");
buy = JO.getString("Buying Price");
sell = JO.getString("Selling Price");
Contacts contacts = new Contacts(id,name,buy,sell);
contactAdapter.add(contacts);
count++;
}
you have to use jsonarray length not the object length.
I followed this tutorial to import database. Then I try to read the data using ArrayList to display them in listview. But I got nullpointer exception on my rawQuery saying it is invoking a null object reference.
DB.java
public class DB extends SQLiteOpenHelper {
//The Android's default system path of your application database.
private static String DB_PATH = "data/data/hairulhazri.malayforyou/databases/";
private static String DB_NAME = "malayforyou";
private static String TABLE_LOCATION = "Frasa";
private final Context context;
private SQLiteDatabase db;
// constructor
public DB(Context context) {
super( context , DB_NAME , null , 1);
this.context = context;
}
// Creates a empty database on the system and rewrites it with your own database.
public void create() throws IOException {
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
// By calling this method and empty database will be created into the default system path
// of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
// Check if the database exist to avoid re-copy the data
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String path = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
// database don't exist yet.
e.printStackTrace();
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
// copy your assets db to the new system DB
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = context.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
//Open the database
public boolean open() {
try {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
return true;
} catch(SQLException sqle) {
db = null;
return false;
}
}
#Override
public synchronized void close() {
if(db != null)
db.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// PUBLIC METHODS TO ACCESS DB CONTENT
// -----------------------------------------------------------------------------------------------------------------
public ArrayList<Frasa> getFrasa(String situation) {
//ArrayList of Frasa class objects
ArrayList<Frasa> arrFrasa = null;
//String query = "SELECT * FROM Frasa WHERE Situation = " + situation;
String selectQuery = "SELECT " +
Frasa.KEY_ID + "," +
Frasa.KEY_PHRASE + "," +
Frasa.KEY_TRANSLATE + "," +
Frasa.KEY_PRONOUNCE +
" FROM " + TABLE_LOCATION + " WHERE situation = " +situation;
db = SQLiteDatabase.openDatabase( DB_PATH + DB_NAME , null, SQLiteDatabase.OPEN_READWRITE);
Cursor curFrasa = db.rawQuery(selectQuery, null);
if (curFrasa != null && curFrasa.moveToFirst()) {
arrFrasa = new ArrayList<Frasa>();
while (curFrasa.isAfterLast() == false) {
//Frasa is a class with list of fields
Frasa fra = new Frasa();
fra.setId(curFrasa.getInt(curFrasa.getColumnIndex(Frasa.KEY_ID)));
fra.setPhrase(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_PHRASE)));
fra.setTranslate(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_TRANSLATE)));
fra.setPronounce(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_PRONOUNCE)));
arrFrasa.add(fra);
curFrasa.moveToNext();
}
}
curFrasa.close();
db.close();
return arrFrasa;
}
}
Frasa.java (Database table and columns)
public class Frasa {
// Labels Table Columns names
public static final String KEY_ID = "id";
public static final String KEY_PHRASE = "phrase";
public static final String KEY_TRANSLATE = "translate";
public static final String KEY_PRONOUNCE = "pronounce";
// property help us to keep data
public int id;
public String situation;
public String phrase;
public String translate;
public String pronounce;
public Frasa() {
}
public Frasa(int id, String situation, String phrase, String translate, String pronounce) {
this.id = id;
this.situation = situation;
this.phrase = phrase;
this.translate = translate;
this.pronounce = pronounce;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPhrase() {
return phrase;
}
public void setPhrase(String phrase) {
this.phrase = phrase;
}
public String getTranslate() {
return translate;
}
public void setTranslate(String translate) {
this.translate = translate;
}
public String getPronounce() {
return pronounce;
}
public void setPronounce(String pronounce) {
this.pronounce = pronounce;
}
}
public class GreetingAdapter extends ArrayAdapter<Frasa> {
Context context;
int layoutResourceId;
ArrayList<Frasa> data = new ArrayList<Frasa>();
public GreetingAdapter(Context context, int layoutResourceId, ArrayList<Frasa> data)
{
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
UserHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new UserHolder();
holder.textPhrase = (TextView) row.findViewById(R.id.textViewPhrase);
holder.textTranslate = (TextView) row.findViewById(R.id.textViewTranslate);
holder.btnSpeak = (Button) row.findViewById(R.id.buttonSpeak);
holder.btnRecord = (Button) row.findViewById(R.id.buttonRecord);
holder.btnPlay = (Button) row.findViewById(R.id.buttonPlay);
row.setTag(holder);
} else {
holder = (UserHolder) row.getTag();
}
Frasa frasa = data.get(position);
holder.textPhrase.setText(frasa.getPhrase());
holder.textTranslate.setText(frasa.getTranslate());
holder.btnSpeak.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Edit Button Clicked", "**********");
Toast.makeText(context, "Speak button Clicked",
Toast.LENGTH_LONG).show();
}
});
holder.btnRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Delete Button Clicked", "**********");
Toast.makeText(context, "Delete button Clicked",
Toast.LENGTH_LONG).show();
}
});
holder.btnPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Play Button Clicked", "**********");
Toast.makeText(context, "Playing recorded audio",
Toast.LENGTH_LONG).show();
}
});
return row;
}
static class UserHolder {
TextView textPhrase;
TextView textTranslate;
Button btnSpeak;
Button btnRecord;
Button btnPlay;
}
}
activity_list_greetings.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txt_header"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Greetings"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/black" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listGreetings"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/txt_header" />
list_item_greet.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textViewPhrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phrase"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_above="#+id/buttonRecord"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/buttonSpeak"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Speak"
android:textColor="#0099CC" />
<Button
android:id="#+id/buttonRecord"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/buttonSpeak"
android:layout_marginTop="3dp"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Record"
android:textColor="#0099CC" />
<Button
android:id="#+id/buttonPlay"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/buttonRecord"
android:layout_marginTop="3dp"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Play"
android:textColor="#0099CC" />
<TextView
android:id="#+id/textViewTranslate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Translate"
android:textSize="20sp"
android:textColor="#color/background_material_dark"
android:layout_below="#+id/buttonRecord"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
ListGreetings.java
public class ListGreetings extends ActionBarActivity {
TextView txtPhrase, txtTranslate;
Button speakButton;
MediaPlayer pronounce;
ListView userList;
GreetingAdapter greetAdapter;
//ArrayList<Frasa> frasaArray = new ArrayList<Frasa>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_greetings);
DB db = new DB(this);
db.open();
//get Frasa data
ArrayList<Frasa> frasaArray = db.getFrasa("Greetings");
/**
* set item into adapter
*/
greetAdapter = new GreetingAdapter(ListGreetings.this, R.layout.list_item_greet, frasaArray);
userList = (ListView) findViewById(R.id.listGreetings);
userList.setItemsCanFocus(false);
userList.setAdapter(greetAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_list_greetings, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Is it my way of calling getFrasa wrong? Or the database cannot be detected? I'm sure I already pushed the database file to both assets folder & inside the package. Sorry, if I'm not formatting the codes correctly. Thanks in advance for any help.
The problem is that you are trying to open the Database from a different location
private static String DB_PATH = "data/data/hairulhazri.malayforyou/databases/";
private static String DB_NAME = "malayforyou";
...
...
db = SQLiteDatabase.openDatabase( DB_PATH + DB_NAME , null, SQLiteDatabase.OPEN_READWRITE);
db is returning NULL because your database is stored in /assets folder not in "data/data/hairulhazri.malayforyou/databases/"
I'm using UIL to load thrumbs in a listview.
here is the imageview and the spinner in the cell layout :
<ImageView
android:id="#+id/imgAlbum"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_gravity="center|left"
android:scaleType="centerCrop"
android:visibility="gone" />
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
The list :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<ListView
android:id="#+id/list_restaurant"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp" >
</ListView>
</LinearLayout>
I config the loader like that :
public void setImageLoader(ImageLoader imageLoader, Context context) {
File cacheDir = StorageUtils.getCacheDirectory(context);
ImageLoaderConfiguration _config;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
_config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0).discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(null)
.taskExecutorForCachedImages(null).threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
.memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
.discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.enableLogging().build();
}
else {
_config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0)
// default/screendimensions
.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(AsyncTask.THREAD_POOL_EXECUTOR).taskExecutorForCachedImages(AsyncTask.THREAD_POOL_EXECUTOR)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
.memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
.discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.enableLogging().build();
}
if (!imageLoader.isInited()) {
imageLoader.init(_config);
}
}
And in the baseadapter i use it like that :
private ImageLoader _imageLoader;
private DisplayImageOptions _options;
in the constructor
this._imageLoader = ImageLoader.getInstance();
this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc().bitmapConfig(Bitmap.Config.RGB_565)
.build();
Utils utils = new Utils();
utils.setImageLoader(_imageLoader, _activity);
In the GetView() :
final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
_imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
view.setVisibility(View.GONE);
spinner.setVisibility(View.VISIBLE);
spinner.invalidate();
view.invalidate();
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
view.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);spinner.invalidate();
view.invalidate();
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
view.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
spinner.invalidate();
view.invalidate();
}
});
Everything works fine BUT the spinner stay instead of the imageview until you scroll the list the redraw the cells.. The imageview should refresh itself when the image is downloaded/got from cache or invalidate()
Here the list loading stay like that : http://imagik.fr/view-rl/45673
Here when i scroll down the imageview refresh : http://imagik.fr/view-rl/45674
Here when i re-scoll up the imageview refresh : http://imagik.fr/view-rl/45675
Any idea ??
EDIT:
The full adapter code (with the UIL part inside) :
public class AdapterDirectories extends BaseAdapter {
/**
* PRIVATE ATTRIBUTES
*/
// LOG
private static final String TAG = AdapterDirectories.class.getSimpleName();
// IHM
private static LayoutInflater _inflater = null;
private Activity _activity;
// DATA
private DataManager _dataManager;
private ImageLoader _imageLoader;
private DisplayImageOptions _options;
private int _section;
private float _latitude;
private float _longitude;
private List<Contact> _listContacts = new ArrayList<Contact>();
private List<Favoris> _listFavoris = new ArrayList<Favoris>();
public AdapterDirectories(Activity activity, boolean favoris, float latitude, float longitude, int section) {
this._activity = activity;
this._latitude = latitude;
this._longitude = longitude;
this._section = section;
//
ContactRepository contactRep = null;
//
if (favoris == false) {
_listContacts = EtablissementApplication._dataManager.get_listOfContacts(_section, _activity);
}
else {
// FAVORITE
this._listFavoris = EtablissementApplication._dataManager.get_listOfFavoris();
// DATA
contactRep = new ContactRepository(_activity);
contactRep.Open();
for (Favoris unFavoris : _listFavoris) {
_listContacts.add(contactRep.GetById(unFavoris.getIdentifiantContact()));
}
contactRep.Close();
}
_inflater = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this._imageLoader = ImageLoader.getInstance();
this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(Utils.IMAGE_BORDER_RADIUS)).bitmapConfig(Bitmap.Config.RGB_565).build();
Utils utils = new Utils();
utils.setImageLoader(_imageLoader, _activity);
}
#Override
public int getCount() {
return _listContacts.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
CellHolder cellHolder = null;
Contact _contact = _listContacts.get(position);
Etablissement etablissement = new Etablissement();
//
// GET
if (convertView == null) {
view = _inflater.inflate(R.layout.directory_list_item, null);
cellHolder = new CellHolder();
cellHolder.textTitle = (TextView) view.findViewById(R.id.annuaire_titre_etablissement);
cellHolder.textCategory = (TextView) view.findViewById(R.id.annuaire_categorie_etablissement);
cellHolder.textDistance = (TextView) view.findViewById(R.id.annuaire_distance_etablissement);
cellHolder.imageIcon = (ImageView) view.findViewById(R.id.img_icon);
cellHolder.textPromo = (TextView) view.findViewById(R.id.promo);
cellHolder.textTarif = (TextView) view.findViewById(R.id.annuaire_tarif_etablissement);
view.setTag(cellHolder);
}
else {
cellHolder = (CellHolder) convertView.getTag();
}
//
// SET
cellHolder.textTitle.setText(_contact.getName().toUpperCase());
try {
//
EtablissementRepository etablissementRep = new EtablissementRepository(_activity);
etablissementRep.Open();
int idEta = etablissementRep.GetByIdContact(_contact.getIdentifiant());
etablissement = etablissementRep.GetById(idEta);
etablissementRep.Close();
// CATEGORIES
if (_section == 0) {
if (etablissement.getSection() != null && !etablissement.getSection().getLibelle().equals("")) {
cellHolder.textCategory.setText(etablissement.getSection().getLibelle());
}
else {
cellHolder.textCategory.setVisibility(View.GONE);
}
}
else {
String categories = "";
for (Categorie cat : etablissement.getCategories()) {
categories = categories + cat.getLibelle() + "|";
}
if (!categories.equals("")) {
cellHolder.textCategory.setText(categories);
}
else {
cellHolder.textCategory.setText(_activity.getString(R.string.txt_no_categories));
}
}
//
// TARIF
String trancheTarif = "";
if (etablissement.getTarif() != null) {
trancheTarif = etablissement.getTarif().getMinPrice() + "\u20ac à " + etablissement.getTarif().getMaxPrice() + "\u20ac";
}
if (!trancheTarif.equals("") && etablissement.getTarif().getMinPrice() > 0 && etablissement.getTarif().getMaxPrice() > 0) {
cellHolder.textTarif.setText(trancheTarif);
}
else {
cellHolder.textTarif.setText("- \u20ac à - \u20ac");
}
// PROMO
boolean etatPromotion = false;
for (Promotion promo : etablissement.getPromotions()) {
if (promo.isPromoOnGoing()) {
etatPromotion = true;
}
}
if (!etatPromotion) { // PROMO OFF
cellHolder.textPromo.setVisibility(View.VISIBLE);
}
else { // PROMO ON
cellHolder.textPromo.setVisibility(View.VISIBLE);
}
// LOGO
final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
_imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
}
});
}
catch (Exception e) {
}
// DISTANCE
int distanceFormatee = 0;
if (_latitude == 0 || _longitude == 0) {
cellHolder.textDistance.setText("");
}
else {
int distance = (int) distanceBetween(_latitude, _longitude, _contact.getLatitude(), _contact.getLongitude());
distanceFormatee = distance / 1000;
if (distance < 1000) {
cellHolder.textDistance.setText("< 1 km");
}
else {
cellHolder.textDistance.setText(distanceFormatee + " km");
}
}
//
// SAVE DISTANCE
EtablissementApplication._dataManager.get_listOfContacts(_section, _activity).get(position).setDistance(distanceFormatee);
//
// DATA SAVE
List<Integer> _mapData = new ArrayList<Integer>();
_mapData.add(_contact.getIdentifiant());
_mapData.add(etablissement.getIdentifiant());
DataManager._contactForEtaHashMap.put(_contact.getName(), etablissement);
DataManager._mapContact.put(position, _mapData);
return view;
}
public class CellHolder {
public TextView textTitle;
public TextView textAdress;
public TextView textCategory;
public TextView textTarif;
public TextView textPromo;
public ImageView imageIcon;
public TextView textDistance;
}
public void clearData() {
_listContacts.clear();
_listFavoris.clear();
}
private double distanceBetween(float lat_a, float lng_a, float lat_b, float lng_b) {
float pk = (float) (180 / 3.14169);
float a1 = lat_a / pk;
float a2 = lng_a / pk;
float b1 = lat_b / pk;
float b2 = lng_b / pk;
float t1 = FloatMath.cos(a1) * FloatMath.cos(a2) * FloatMath.cos(b1) * FloatMath.cos(b2);
float t2 = FloatMath.cos(a1) * FloatMath.sin(a2) * FloatMath.cos(b1) * FloatMath.sin(b2);
float t3 = FloatMath.sin(a1) * FloatMath.sin(b1);
double tt = Math.acos(t1 + t2 + t3);
return 6366000 * tt;
}
}
You can achieve expected behaviour by this:
Your list item layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<ImageView
android:id="#+id/imgAlbum"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_gravity="center|left"
android:scaleType="centerCrop" />
</RelativeLayout
If you have ProgressBar and ImageView in this order, then ImageView will overlay the ProgressBar, when Image Loader set image into it so ProgressBar will not be visible anymore.
Then in your getView() method just simply load image with standard way. You dont have to bother with hiding/showing ProgressBar
You will have to put a function to refresh the 'source' that is providing the image resource to the spinner manually once the download is complete i.e i suppose when an onPost is complete in your async task if at all u are using one. This way the source providing the resource to the spinner will be updated all the time.
try this code and use Asynk task will help u:
http://thinkandroid.wordpress.com/2012/06/13/lazy-loading-images-from-urls-to-listviews/