An activity with a listview has a problem that is, the listview will have different amount of content in each cell. When the user scrolls down, the listview is smooth and things work as expected. But, when the user scrolls up, the cached data of the listview is reloaded. This redraw is making the listview scrolling up jumpy. What I figured out is that, if I calculate the height of each cell while scrolling down and save it in an ArrayList and apply the same height when the user scrolls up against the visible listitem then the jumpy scroll can be fixed. I have tested the same by setting a static height for every post, the scrollbar was not jumpy. But, I have to make it dynamic according to each cell height. The listview code might look to be a little complex!
The activity:
public class PostListActivity extends Activity implements OnScrollListener {
TableLayout html_output_table;
int id = 0;
List<String> dataFromParse = new ArrayList<String>();
LazyObjectDrawingAdapter adapter;
ListView listView;
List<RichPost> richPostArrayList = new ArrayList<RichPost>();
private int currentScrollState;
private int currentVisibleItemCount;
private int skipParam = 0;
private boolean flag_loading = false;
int mLastFirstVisibleItem = 0;
HashMap<integer, String> hashMap = new HashMap<integer, String>();
int initialHeight = 0;
ArrayList<Integer> heightList = new ArrayList<Integer>();
int position;
boolean scrolling = false;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_list_list);
listView = (ListView) findViewById(R.id.listView);
// Need to create the adapter constructor
listView.setOnScrollListener(this);
adapter = new LazyObjectDrawingAdapter(PostListActivity.this, dataFromParse, richPostArrayList);
listView.setAdapter(adapter);
setContent();
// cityListBody("Hello");
}
public void setContent(){
// Pull data from Parse
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("userid", ParseUser.getCurrentUser().getObjectId());
params.put("skip", skipParam);
ParseCloud.callFunctionInBackground("studentsPosts", params, new FunctionCallback<List<List<ParseObject>>>() {
#Override
public void done(List<List<ParseObject>> data, com.parse.ParseException arg1){
if (data == null) {
} else {
Log.e("size ", "RUNNING Size : " + data.size());
if (data.size() > 0) {
flag_loading = false;
for (int i = 0; i < data.size(); i++) {
RichPost rc = new RichPost();
//if (heightList.size()>i){
Log.e("heightList.size()", ""+heightList.size());
//}
if (data.get(0).get(0).get("htmlContent") != null) {
// Switch i to 1 to force just 1 additon.
dataFromParse.add(data.get(i).get(0).getString("htmlContent"));
rc.setHtmlCode(data.get(i).get(0).getString("htmlContent"));
Log.i("Calling notifiyDataSetchanged", "now");
}
if (data.get(i).get(0).get("photos") != null) {
List<ParseFile> pFileList;
pFileList = (List<ParseFile>) data.get(i).get(0).get("photos");
rc.setPhotosArray(pFileList);
}
if (data.get(i).get(0).getParseFile("photo") != null) {
// Time to retrieve the photo
ParseFile getParseFile;
getParseFile = (ParseFile) data.get(i).get(0).get("photo");
rc.setPhoto(getParseFile);
}
richPostArrayList.add(rc);
adapter.notifyDataSetChanged();
}
}
}
}
});
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState){
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
private void isScrollCompleted(){
if (this.currentVisibleItemCount >= 5 && this.currentScrollState == SCROLL_STATE_IDLE) {
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){
this.currentVisibleItemCount = visibleItemCount;
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount != 0) {
if (flag_loading == false) {
flag_loading = true;
Log.d("IN ON SCROLL", "NOW: " + skipParam);
skipParam = skipParam + 10;
setContent();
}
}
// to determine scroll up or down
if (mLastFirstVisibleItem < firstVisibleItem) {
Log.i("SCROLLING DOWN", "TRUE");
// View c = listView.getChildAt(0);
// int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
// Log.e("scrolly", "" + scrolly);
int scrolly = getItemHeightofListView(listView, firstVisibleItem);
Log.e("scrolly down", "" + scrolly);
//setting the cell height from total height - initial height
heightList.add(scrolly-initialHeight);
ArrayListGetterSetter test = new ArrayListGetterSetter();
test.setList(scrolly-initialHeight);
initialHeight = scrolly;
//hashMap.put(firstVisibleItem, "" + scrolly);
//Log.e("Item show",""+heightList.get(firstVisibleItem));
scrolling = true;
}
if (mLastFirstVisibleItem > firstVisibleItem) {
Log.i("SCROLLING UP", "TRUE");
// View c = listView.getChildAt(0);
// int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
// Log.e("scrolly", "" + scrolly);
// int scrolly = getItemHeightofListView(listView, firstVisibleItem);
// Log.e("scrolly up", "" + scrolly);
if (firstVisibleItem <= heightList.size()) {
//getting the heights from the arraylist while scrolling up
//Log.e("Item show",""+heightList.get(firstVisibleItem));
position = firstVisibleItem;
}
}
mLastFirstVisibleItem = firstVisibleItem;
}
public static int getItemHeightofListView(ListView listView, int items) {
ListAdapter mAdapter = listView.getAdapter();
int listviewElementsheight = 0;
// for listview total item height
// items = mAdapter.getCount();
for (int i = 0; i < items; i++) {
View childView = mAdapter.getView(i, null, listView);
childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
listviewElementsheight+= childView.getMeasuredHeight();
}
return listviewElementsheight;
}
}
The adapter:
public class LazyObjectDrawingAdapter extends BaseAdapter {
PostListActivity postList = new PostListActivity();
RichPost rc = new RichPost();
Context mContext;
List<String> randomItems = new ArrayList<String>();
List<RichPost> richPostArrayList = new ArrayList<RichPost>();
private LayoutInflater inflater = null;
ArrayList<Integer> heightList = new ArrayList<Integer>();
public LazyObjectDrawingAdapter(Context context, List<String> contentComingIn, List<RichPost> richPostArrayList) {
this.mContext = context;
this.inflater = LayoutInflater.from(mContext);
this.randomItems = contentComingIn;
this.richPostArrayList = richPostArrayList;
}
// public LazyObjectDrawingAdapter(Context context, List<String> contentComingIn, List<RichPost> richPostArrayList, ArrayList<Integer> heightList) {
// this.mContext = context;
// this.inflater = LayoutInflater.from(mContext);
// this.randomItems = contentComingIn;
// this.richPostArrayList = richPostArrayList;
// this.heightList = heightList;
//
// }
#Override
public int getCount() {
//return 1;
//Log.i("GetCount size : ", " " + randomItems.size());
//return 1;
return randomItems.size();
}
#Override
public Object getItem(int position) {
return randomItems.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.lazy_adapter, null);
holder = new ViewHolder();
setIds(vi, holder);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
ArrayListGetterSetter test = new ArrayListGetterSetter();
Log.e("test.getSize()", ""+test.getSize());
//test.getListValues(position);
tryingNewClass(holder, vi, mContext, (String) randomItems.get(position), richPostArrayList.get(position));
return vi;
}
private void step1(String fromActivity) {
Log.d("Html output", "" + fromActivity);
}
private void step2(String html){
Document doc = Jsoup.parse(html);
Element element = doc.body();
Elements elements = element.select("img");
Log.w("Size of the elements ", " " + elements.size());
for(Element e : elements){
Log.d("step 2: ", "img: " + e.toString());
}
}
private void step2PicksUpWorks(String html){
Document doc = Jsoup.parse(html);
Elements imgs = doc.body().select("p");
for (Element e : imgs){
if(!e.toString().contentEquals("")){
Log.i("Img sources ", ": " + e.ownText());
}
}
}
private void tryingNewClass(ViewHolder holder, View view, Context context, String source, RichPost richPost){
//setting static height for testing, feel free to remove it anytime
int heightValue = 500;
holder.textToDraw.setMinHeight(heightValue + 200);
TestDrawableClass tdc = new TestDrawableClass(source, holder.textToDraw, context, holder.imageToDraw, richPost);
}
private void URLCombinedTest(int position, ViewHolder holder, View view, Context context, String source){
ImageView iv = new ImageView(context);
TextView tv = new TextView(context);
URLCombined uip = new URLCombined(position, iv, context, tv);
Spanned spanned = Html.fromHtml(source, uip, null);
tv.setText(spanned);
//holder.linearLayoutForImages.addView(iv);
holder.linearLayoutForImages.addView(tv);
}
/*
* Time to do the on draw
*/
private void lineByLine(int position, ViewHolder holder, View view, Context context, String source){
//Need to get line by line and then run it via the test parsers and add it to the layout dynmically via the ViewGrou parpent
Document doc = Jsoup.parse(source);
Element element = doc.body();
Elements ele = element.select("img");
for (int i = 0; i < ele.size(); i++) {
/* Log.w("For loop ", " " + i + " "+ ele.get(i).html());
Log.d("For loop ", " " + i + " "+ ele.get(i).text());
Log.i("For loop ", " " + i + " "+ ele.get(i));*/
addURLImageParser(position, holder, view, context, ""+ele.get(i));
}
Elements all = doc.select("b");
for (int i = 0; i < all.size(); i++) {
Log.i("For loop ", " " + i + " "+ all.get(i));
addURLTextParser(position, holder, view, context, ""+all.get(i));
}
Log.w("About to start a loop to check everything ", "now");
int imgValue = 0;
for (Element el:doc.select("body").select("*")) {
imgValue++;
// loop over all textnodes of these children
Log.i("Element siblings ", " " + el.nextElementSibling() + " " +imgValue);
Element tempElement = el.nextElementSibling();
if(el.nextElementSibling() == null){
Log.w("Element is null", "value is : " + el + " " + imgValue);
}
if(el.nextElementSibling() != null){
//Loop through the siblings.
if(el.nextElementSibling().hasText()){
//Log.d("Can we check any text after the fact ? ", " " + el);
//Log.e("Element has text: ", " " + el.nextElementSibling());
}
if(el.nextElementSibling().hasText() == false){
Elements elements = tempElement.select("img");
if(elements.isEmpty() == false){
//Log.e("Element text is false ", " " + elements);
}
}
}
imgValue = 0;
}
}
private void addURLTextParser(int position, ViewHolder holder, View view, Context context, String source){
Log.w("in add text url", "now");
TextView tv = new TextView(context);
URLTextParser utp = new URLTextParser(tv, context, 0);
Spanned spanned = Html.fromHtml(source, utp, null);
tv.setText(spanned);
holder.linearLayoutForImages.addView(tv);
//Now attach it the layout
}
private void addURLImageParser(int position, ViewHolder holder, View view, Context context, String source){
//Log.w("in add image url", "now");
ImageView iv = new ImageView(context);
URLImageParser uip = new URLImageParser(position, iv, context);
Spanned spanned = Html.fromHtml(source, uip, null);
holder.linearLayoutForImages.setId(position);
holder.linearLayoutForImages.addView(iv);
}
private void testURLTextParser(int position, ViewHolder holder, View view, Context context, String source){
//Lets just get text only
Document doc = Jsoup.parse(source);
Elements img = doc.body().select("p");
for (int i = 0; i < img.size(); i++) {
//Log.w("Checking null ", " " + img.get(i).text().contentEquals(""));
if( img.get(i).text().contentEquals("") == false){
Log.i("output : ", " " + img.get(i).text());
Log.d("Output2 ", " " + img.get(i).html());
URLTextParser utp = new URLTextParser(holder.textToDraw, context, 0);
Spanned spanned = Html.fromHtml(img.get(i).html(), utp, null);
holder.textToDraw.setText(spanned);
}
}
}
private void testURLImageParser(int position, ViewHolder holder, View view, Context context, String source){
//Log.d("In step 3 ", " Position : " + position);
//Lets do some crazy work right now. So lets start with just images. Make them 3 seperate ImageViews to draw
//Pos 0 has three images, but lets cycle throgh the mfirst
Document doc = Jsoup.parse(source);
Elements img = doc.body().select("img");
//Now we have all possible image 'source links'
for (int i = 0; i < img.size(); i++) {
//Lets loop through them one by one
Log.w("checking the output of the img ", "" + img.get(i).toString());
ImageView iv = new ImageView(context); //Create a holder for the images
URLImageParser uip = new URLImageParser(position, iv, context);
Spanned spanned = Html.fromHtml(img.get(i).toString(), uip, null);
holder.linearLayoutForImages.addView(iv);
}
}
private void setIds(View vi, ViewHolder holder) {
holder.textToDraw = (TextView) vi.findViewById(R.id.textOnly);
holder.imageToDraw = (ImageView) vi.findViewById(R.id.imageOnly);
holder.linearLayoutForImages = (LinearLayout) vi.findViewById(R.id.linearForImages);
}
static class ViewHolder {
TextView textToDraw;
ImageView imageToDraw;
Object objectCouldBeAnything;
Canvas toTry;
LinearLayout linearLayoutForImages;
}
}
Class ArrayListGetterSetter:
public class ArrayListGetterSetter {
ArrayList<Integer> heightList = new ArrayList<Integer>();
int valueFromList;
int size;
public int getListValues(int itemIndex) {
valueFromList = heightList.get(itemIndex);
return valueFromList;
}
public void setList(int value) {
heightList.add(value);
}
public int getSize(){
size = heightList.size();
return size;
}
}
Class TestDrawableClass:
Click to see the code
The
ArrayListGetterSetter test = new ArrayListGetterSetter();
Log.e("test.getSize()", ""+test.getSize());
in the LazyObjectDrawingAdapter is always returning 0. Thus querying the elements are causing null pointer exception. How can I get the height values?
in getItemId you should have returned position instead of zero.
#Override
public long getItemId(int position) {
return 0;
}
it should be :
#Override
public long getItemId(int position) {
return position;
}
i think this might help.
Related
I want to make view by adding child list on android using cardview in recycleview.
i have made class to store these item and make arraylist on each parent of object if the object have child item, so i can differentiate if the list has child or not.
But i have difficulties to render the same layout to make the child list below the parent list. I am pragmatically make the layout one by one but it will be difficult to make that. So i want to render the same layout to my adapter when i want to make a child list whenever the object/class has arraylist of child list in that object.
this is my adapter right now
public class NotificationListAdapter extends BaseListAdapter<NotificationData, NotificationListAdapter.CustomViewHolder> {
private List<NotificationData> notificationData;
private ArrayList<Integer> indexForHide;
public NotificationListAdapter(Context context) {
super(context);
}
#Override
public void addAll(List<NotificationData> items) {
super.addAll(items);
this.notificationData = items;
}
void setChildNotif(){
ArrayList<NotificationData> childDataItems;
List<NotificationData> notificationDataChild = new ArrayList<NotificationData>();
notificationDataChild.addAll(notificationData);
indexForHide = new ArrayList<Integer>();
for (int i = 0; i < notificationData.size(); i++) {
childDataItems = new ArrayList<>();
if (notificationDataChild.size() == 1) {
notificationData.get(i).setChildNotification(childDataItems);
break;
}
for (int j = i; j < notificationDataChild.size(); j++){
if(i==j){
continue;
}else if (notificationDataChild.size() == 1) {
notificationData.get(i).setChildNotification(childDataItems);
break;
}else{
if(notificationDataChild.get(j).getRfqId()!=0){
if(notificationDataChild.get(j).getRfqId()==notificationData.get(i).getRfqId()){
childDataItems.add(notificationDataChild.get(j));
indexForHide.add(j);
}
}
if(!notificationDataChild.get(j).getInvoiceNumber().equalsIgnoreCase("")) {
if (notificationDataChild.get(j).getInvoiceNumber().equalsIgnoreCase(notificationData.get(i).getInvoiceNumber())) {
childDataItems.add(notificationDataChild.get(j));
indexForHide.add(j);
}
}
}
}
notificationData.get(i).setChildNotification(childDataItems);
Log.d("sizeNotif", i+" :"+notificationData.get(i).getChildNotification().size());
}
Log.d("sizeNotification", " :"+notificationData.size());
Log.d("sizeNotificationDummy", " :"+notificationData.size());
Log.d("isiHideAdapter", Arrays.toString(indexForHide.toArray()));
Log.d("isiHideAdapterSize", indexForHide.size()+"");
}
#Override
protected int getItemResourceLayout(int viewType) {
return R.layout.item_notification_list;
}
int position;
#Override
public int getItemViewType(int position) {
this.position = position;
return position;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
setChildNotif();
return new CustomViewHolder(getView(parent, viewType), onItemClickListener);
}
public class CustomViewHolder extends BaseViewHolder<NotificationData> {
private TextView tvNotifTitle, tvNotifBody, tvNotifStatus, tvNotifTime, tvSignUnread, tvHeaderTitle;
private CardView formContent;
private LinearLayout linearLayout_childItems;
private ImageView expandList;
public CustomViewHolder(View itemView, OnItemClickListener onItemClickListener) {
super(itemView, onItemClickListener);
tvNotifTitle = itemView.findViewById(R.id.tvNotifTitle);
tvNotifBody = itemView.findViewById(R.id.tvNotifBody);
// tvNotifStatus = itemView.findViewById(R.id.tvNotifStatus);
tvNotifTime = itemView.findViewById(R.id.tvNotificationTime);
formContent = itemView.findViewById(R.id.formContent);
tvSignUnread = itemView.findViewById(R.id.tvSignUnread);
tvHeaderTitle = itemView.findViewById(R.id.tvHeaderNotifList);
linearLayout_childItems = itemView.findViewById(R.id.ll_child_items);
expandList = itemView.findViewById(R.id.arrow_expand_notif_list);
//SET CHILD
int intMaxNoOfChild = 0;
for (int index = 0; index < notificationData.size(); index++) {
int intMaxSizeTemp = notificationData.get(index).getChildNotification().size();
if (intMaxSizeTemp > intMaxNoOfChild) intMaxNoOfChild = intMaxSizeTemp;
}
linearLayout_childItems.removeAllViews();
for (int indexView = 0; indexView < intMaxNoOfChild; indexView++) {
TextView textView = new TextView(context);
textView.setId(indexView);
textView.setPadding(20, 20, 0, 20);
textView.setGravity(Gravity.LEFT);
textView.setTextSize(14);
textView.setTextColor(ContextCompat.getColor(context, R.color.colorText));
textView.setBackground(ContextCompat.getDrawable(context, R.drawable.bg_sub_notif_text));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.leftMargin = 16;
textView.setOnClickListener(this);
linearLayout_childItems.addView(textView, layoutParams);
}
}
#Override
public void bind(NotificationData item) {
String title = splitString(item.getTitle());
tvNotifTitle.setText(title);
tvNotifBody.setText(item.getContent());
String txtTime = item.getCreatedAtDisplay().replaceAll("WIB", "");
tvNotifTime.setText(txtTime);
if (position == 0) {
((ViewGroup.MarginLayoutParams) formContent.getLayoutParams()).topMargin = dpToPx(12);
}
((ViewGroup.MarginLayoutParams) formContent.getLayoutParams()).bottomMargin = dpToPx(12);
if (position == getItemCount() - 1) {
((ViewGroup.MarginLayoutParams) formContent.getLayoutParams()).bottomMargin = dpToPx(80);
}
if(item.getIsRead()==1){
formContent.setCardBackgroundColor(context.getResources().getColor(R.color.gray1));
formContent.setCardElevation(5);
formContent.setRadius(15);
tvSignUnread.setVisibility(View.GONE);
}else if(item.getIsRead()==0){
}
//setHeader
Calendar calendar;
SimpleDateFormat dateFormat;
calendar = Calendar.getInstance();
dateFormat = new SimpleDateFormat("yyyy-MM-dd") ;
String date, yesterdayDate, dateDisplayData, dateData;
date = dateFormat.format(calendar.getTime());
calendar.add(Calendar.DATE, -1);
yesterdayDate = dateFormat.format(calendar.getTime());
String[] arrDateDisplayData = item.getCreatedAtDisplay().split(",", 5);
dateDisplayData = arrDateDisplayData[0];
String[] arrDateData = item.getCreatedAt().split(" ", 5);
dateData = arrDateData[0];
Log.d("datenow", date);
Log.d("dateyesterday", yesterdayDate);
Log.d("dateDisplayData", dateDisplayData);
Log.d("dateData", dateData);
if(dateData.equalsIgnoreCase(date)){
tvHeaderTitle.setText("Hari ini");
}else if(dateData.equalsIgnoreCase(yesterdayDate)){
tvHeaderTitle.setText("Kemarin");
}else{
tvHeaderTitle.setText(dateDisplayData);
// tvHeaderTitle.setVisibility(View.GONE);
}
if (getAdapterPosition() > 0) {
String[] timePrev = notificationData.get(getAdapterPosition() - 1).getCreatedAt().split(" ");
if (dateData.equalsIgnoreCase(timePrev[0])) {
tvHeaderTitle.setVisibility(View.GONE);
}
}
if(indexForHide.contains(getAdapterPosition())){
formContent.setVisibility(View.GONE);
}
//SET CHILD
NotificationData dummyParentDataItem = notificationData.get(position);
int noOfChildTextViews = linearLayout_childItems.getChildCount();
for (int index = 0; index < noOfChildTextViews; index++) {
TextView currentTextView = (TextView) linearLayout_childItems.getChildAt(index);
currentTextView.setVisibility(View.VISIBLE);
}
int noOfChild = 0;
if(dummyParentDataItem.getChildNotification()==null){
noOfChild = 0;
}else{
noOfChild = dummyParentDataItem.getChildNotification().size();
}
if (noOfChild < noOfChildTextViews) {
for (int index = noOfChild; index < noOfChildTextViews; index++) {
TextView currentTextView = (TextView) linearLayout_childItems.getChildAt(index);
// currentTextView.setVisibility(View.GONE);
}
}
for (int textViewIndex = 0; textViewIndex < noOfChild; textViewIndex++) {
TextView currentTextView = (TextView) linearLayout_childItems.getChildAt(textViewIndex);
currentTextView.setText(dummyParentDataItem.getChildNotification().get(textViewIndex).getTitle());
/*currentTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext, "" + ((TextView) view).getText().toString(), Toast.LENGTH_SHORT).show();
}
});*/
}
if (noOfChild > 0) {
expandList.setVisibility(View.VISIBLE);
expandList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (linearLayout_childItems.getVisibility() == View.VISIBLE) {
linearLayout_childItems.setVisibility(View.GONE);
// Toast.makeText(context, "expand", Toast.LENGTH_SHORT).show();
expandList.setImageResource(R.drawable.ic_arrow_up_blue);
}
else {
linearLayout_childItems.setVisibility(View.VISIBLE);
expandList.setImageResource(R.drawable.ic_arrow_down_blue);
}
}
});
}else {
linearLayout_childItems.setVisibility(View.GONE);
}
}
public int dpToPx(int dp) {
Resources r = context.getResources();
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp, r.getDisplayMetrics()
);
return px;
}
public String splitString(String tempString){
StringBuilder finalString = new StringBuilder(tempString);
int i = 0;
while ((i = finalString.indexOf(" ", i + 20)) != -1) {
finalString.replace(i, i + 1, "\n");
}
return finalString.toString();
}
}
}
please help me to render my layout whenever i want to make a child list under my parent list so i can simplify my code above and not making the child layout programatically
I'm creating an app where I have radio group with three radio buttons. What I want is when I check the radio button I need to get the id value of that radio button and save it in array or database and then count the id value.
For example i have this radiogroup in 19 fragment. which is each radiobutton has id value. if the button selected, it will get the id and store it so i can count the selected id value.
this is the display of my stepperstone
My StepFragment
Bundle bundle = this.getArguments();
Log.d("##", "onCreateView: " + bundle.getInt(MyStepperAdapter.CURRENT_STEP_POSITION_KEY)) ;
View view = inflater.inflate(R.layout.fragment_step_fragment_example, container, false);
mRadioGroup = view.findViewById(R.id.radioGroupWrapper);
mRadioGroup.getCheckedRadioButtonId();
DatabaseHelper mDBHelper = new DatabaseHelper(getContext());
Log.d("#######", String.valueOf(bundle.getInt(MyStepperAdapter.CURRENT_STEP_POSITION_KEY)));
final List<Klasifikasi> lk = mDBHelper.getListKlasifikasiByGroup(String.valueOf(Integer.valueOf(bundle.getInt(MyStepperAdapter.CURRENT_STEP_POSITION_KEY)) + 1));
final RadioButton[] rb = new RadioButton[lk.size()];
Log.d("##sz", "onCreateView: " + lk.size()) ;
int[][] states = new int[][] {
new int[] { android.R.attr.state_enabled}, // enabled
new int[] {-android.R.attr.state_enabled}, // disabled
new int[] {-android.R.attr.state_checked}, // unchecked
new int[] { android.R.attr.state_pressed} // pressed
};
int[] colors = new int[] {
Color.BLACK,
Color.BLACK,
Color.BLACK,
Color.BLACK
};
mRadioButton1 = view.findViewById(R.id.checkbox1);
mRadioButton2 = view.findViewById(R.id.checkbox2);
mRadioButton3 = view.findViewById(R.id.checkbox3);
if(lk.size() > 0) {
Klasifikasi kl0 = lk.get(0);
Klasifikasi kl1 = lk.get(1);
Klasifikasi kl2 = lk.get(2);
mRadioButton1.setText(kl0.getKlasifikasi());
mRadioButton2.setText(kl1.getKlasifikasi());
mRadioButton3.setText(kl2.getKlasifikasi());
}
My StepperAdapter
public static final String CURRENT_STEP_POSITION_KEY = "CURRENT_STEP_POSITION_KEY";
public MyStepperAdapter(FragmentManager fm, Context context) {
super(fm, context);
}
#Override
public Step createStep(int position) {
final StepFragmentExample step = new StepFragmentExample();
Bundle b = new Bundle();
b.putInt(CURRENT_STEP_POSITION_KEY, position);
step.setArguments(b);
return step;
}
#Override
public int getCount() {
return 19;
}
#NonNull
#Override
public StepViewModel getViewModel(#IntRange(from = 0) int position) {
//Override this method to set Step title for the Tabs, not necessary for other stepper types
return new StepViewModel.Builder(context)
.setTitle("Fragment " + getCount()) //can be a CharSequence instead
.create();
}
ListKlasifikasiAdapter
public ListKlasifikasiAdapter.KlasifikasiViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
View view = layoutInflater.inflate(R.layout.item_listklasifikasi, viewGroup, false);
KlasifikasiViewHolder klasifikasiViewHolder = new KlasifikasiViewHolder(view);
klasifikasiViewHolder.setIsRecyclable(false);
return klasifikasiViewHolder;
}
#Override
public void onBindViewHolder(#NonNull KlasifikasiViewHolder klasifikasiViewHolder, int i) {
final List<Klasifikasi> lk = mDBHelper.getListKlasifikasiByGroup(String.valueOf(mKlasifikasiList.get(i).getGroup_index()));
final RadioButton[] rb = new RadioButton[lk.size()];
for (int j = 0; j < lk.size(); j++) {
Klasifikasi kl = lk.get(j);
rb[j] = new RadioButton(mContext);
rb[j].setId(j);
rb[j].setText(kl.getKlasifikasi());
klasifikasiViewHolder.radioGroup.addView(rb[j]);
}
}
class KlasifikasiViewHolder extends RecyclerView.ViewHolder {
private RadioGroup radioGroup;
public KlasifikasiViewHolder(#NonNull View itemView) {
super(itemView);
radioGroup = itemView.findViewById(R.id.radioGroupWrapper);
}
}
MyDatabaseHelper
public List<Klasifikasi> getListKlasifikasiByGroup(String index){
Klasifikasi klasifikasi = null;
List<Klasifikasi> klasifikasiList = new ArrayList<>();
openDatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM klasifikasi k WHERE k.group_index = ? ORDER BY k.kategori_id ASC", new String[] {index});
cursor.moveToFirst();
while (!cursor.isAfterLast()){
klasifikasi = new Klasifikasi(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3), cursor.getInt(4));
klasifikasiList.add(klasifikasi);
cursor.moveToNext();
}
cursor.close();
closeDatabase();
ga ada yg jawab T^T cries in the corner
I am using a GridView 6*6 and it consists of EditText for a total of 36 EditText.
I am passing a 2D array from the base class and the values are filled in the correct position. The boxes which are not filled are made invisible.
Now I need to find the first visible EditText box and make focus automatically, and after certain event I need to change the focus to next visible EditText?
#Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
ViewHolder viewHolder;
viewHolder = new ViewHolder();
String comonchar = String.valueOf(hint_lilst.get(0));
if (convertView == null) {
convertView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.crossword_play_screen_items, null);
viewHolder.tv1 = (EditText) convertView.findViewById(R.id.CW_oneone);
viewHolder.gridView = convertView.findViewById(R.id.Cw_gridviewplay);
convertView.setTag(viewHolder);
viewHolder.tv1.setInputType(InputType.TYPE_NULL);
Log.d("macantiosh","child at "+viewGroup.getChildAt(21));
} else {
viewHolder = (ViewHolder)convertView.getTag();
// arrayList.get(position);
viewHolder.tv1.setText(arrayList.get(position));
}
// if (Objects.equals(arrayList.get(position), "0")) {
// viewHolder.tv1.setVisibility(View.INVISIBLE);
// viewHolder.tv1.setClickable(false);
// }
//
if (Objects.equals(arrayList.get(position), comonchar)) {
viewHolder.tv1.setText(arrayList.get(position));
viewHolder.tv1.setBackgroundResource(R.drawable.puzzlesucess);
viewHolder.tv1.setTextColor(Color.parseColor("#FFFFFF"));
}else if (Objects.equals(arrayList.get(position), "0")) {
viewHolder.tv1.setVisibility(View.INVISIBLE);
viewHolder.tv1.setClickable(false);
} else {
// for(int m = 0; m< filled_pos_llist.size();m++){
// if(Objects.equals(arrayList.get(position),focus_pos_wrds.get(filled_pos_llist.get(0)))){
viewHolder.tv1.setText("");
// viewHolder.tv1.setBackgroundResource(R.drawable.puzzlesucess);
//viewHolder.tv1.setTextColor(Color.parseColor("#FFFFFF"));
// viewHolder.tv1.requestFocus();
Log.d("popi", "list words" + arrayList.get(position));
// }
// }
}
if (viewHolder.tv1.getVisibility() ==View.VISIBLE){
filled_pos_llist.add(position);
}
Log.d("adgads","words in list pos "+viewGroup.getChildCount());
//GridView mGridView =viewGroup;
// final int size = viewGroup.getChildCount();
// Log.d("timber","child count in grid view "+size);
// for(int i = 0; i < size; i++) {
// ViewGroup gridChild = (ViewGroup) viewGroup.getChildAt(i);
// int childSize = gridChild.getChildCount();
// for(int k = 0; k < childSize; k++) {
// if( gridChild.getChildAt(k) instanceof EditText ) {
// gridChild.getChildAt(k).setVisibility(View.GONE);
// Log.d("khaggj","got pos list visible positionss ");
// }
// }
// }
// for (Map.Entry<Integer, String> entry : focus_pos_wrds.entrySet()) {
//
// viewHolder.tv1.requestFocus(1);
// viewHolder.tv1.setBackgroundResource(R.drawable.puzzlesucess);
// viewHolder.tv1.setTextColor(Color.parseColor("#FFFFFF"));
//
// Log.d("khaggj","got pos list "+entry.getKey());
// break;
//
//
// }
final ViewHolder finalViewHolder = viewHolder;
viewHolder.tv1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
Log.d("djhgfj", "on focus change lisiner " + position);
finalViewHolder.id = position;
current = (EditText) view;
current.setBackgroundResource(R.drawable.focusedtxt);
click_pos = position;
Log.d("djhgfj", "on focus change lisiner " + finalViewHolder.id);
}
}
});
keyboard.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#SuppressLint("SetTextI18n")
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.d("clickk", "clicked item " + keyboard_words.get(i) + " n " );
EditText current_edittext = getCurrentEditText();
if (current_edittext != null) {
if (current_edittext.getText().length() == 0) {
current_edittext.setText(current.getText().toString() + keyboard_words.get(i));
}
if (current_edittext.getText().toString().equals(arrayList.get(click_pos))) {
Log.d("txtchange", " filled answer crrt ");
current_edittext.setBackgroundResource(R.drawable.puzzlesucess);
current_edittext.setTextColor(Color.parseColor("#FFFFFF"));
// if(Objects.equals(arrayList.get(position),focus_pos_wrds.get(filled_pos_llist.get(0)))){
// viewHolder.tv1.setText("");
// viewHolder.tv1.setBackgroundResource(R.drawable.puzzlesucess);
// viewHolder.tv1.setTextColor(Color.parseColor("#FFFFFF"));
// viewHolder.tv1.requestFocus();
// Log.d("popi", "list words" + arrayList.get(position));
// current = viewHolder.tv1;
// current.setBackgroundResource(R.drawable.focusedtxt);
// click_pos = posiztion;
// }
} else {
Animation shake = AnimationUtils.loadAnimation(context, R.anim.shake);
current_edittext.startAnimation(shake);
current_edittext.setText("");
}
}
Log.d("pendrive", "adapter clicked class " + keyboard_words.get(i) + " current " + click_pos);
}
});
// for (int i = 0; i < filled_pos_llist.size(); i++) {
//
// ViewGroup gridChild = (ViewGroup) viewGroup.getChildAt(i);
//
// if (gridChild.getChildAt(i) instanceof EditText && ((EditText) gridChild.getChildAt(i)).getText().length()>0){
//
// Log.d("thanaser", "visible individual positions ");
//
// }
//
// }
final EditText current_edittext = getCurrentEditText();
if (current_edittext!=null){
current_edittext.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (current_edittext.getText().toString().length()>0){
Log.d("hdjhiu","text changed ");
}
}
});
}
return convertView;
}
I would do it by going throw all GridLayout child Views:
public void setFocusOnEditText() {
GridLayout layout = findViewById(R.id.layout);
layout.getChildCount();
for (int i = 0; i < layout.getChildCount(); i++) {
View view = layout.getChildAt(i);
if (view instanceof EditText && view.getVisibility() == View.VISIBLE) {
view.requestFocus();
}
}
}
If you are using your custom BaseAdapter and if I'm not mistaken you could use:
if (convertView instanceof GridLayout) {
View editText = ((GridLayout) convertView).getChildAt(position);
if (editText instanceof EditText && editText.getVisibility() == View.VISIBLE) {
editText.requestFocus();
}
}
This question already has answers here:
Why does my ArrayList contain N copies of the last item added to the list?
(5 answers)
Closed 5 years ago.
In my android app, I am using recycler view to show items.
(Note: This is not a duplicate question because I tried many answers from stackoverflow but no solution.)
My Problem
The recycler view showing repeated items. A single item is repeating many times even though it occurs only single time in the source DB.
I checked for the reason and note that the List object in Adapter class returning same values in all iterations. But the Fragment that sends List object to adapter class having unique values.
But only the adapter class after receiving the List object contains duplicate items
Solutions I tried
I checked Stackoverflow and added getItemId(int position) and getItemViewType(int position) in adaptor class but no solution
I checked the DB and also List view sending class both dont have duplicate items.
My Code:
InboxHostFragment.java = This class sends List object to adaptor class of recycler view:
public class HostInboxFragment extends Fragment {
View hostinbox;
Toolbar toolbar;
ImageView archive, alert, search;
TextView blank;
Bundle args = new Bundle();
private static final String TAG = "Listinbox_host";
private InboxHostAdapter adapter;
String Liveurl = "";
RelativeLayout layout, host_inbox;
String country_symbol;
String userid;
String login_status, login_status1;
ImageButton back;
String roomid;
RecyclerView listView;
String name = "ramesh";
private int start = 1;
private List < ListFeed > movieList = new ArrayList < > ();
String currency1;
// RecyclerView recyclerView;
public HostInboxFragment() {
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#RequiresApi(api = Build.VERSION_CODES.M)
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
hostinbox = inflater.inflate(R.layout.fragment_host_inbox, container, false);
FontChangeCrawler fontChanger = new FontChangeCrawler(getContext().getAssets(), getString(R.string.app_font));
fontChanger.replaceFonts((ViewGroup) hostinbox);
SharedPreferences prefs = getActivity().getSharedPreferences(Constants.MY_PREFS_NAME, MODE_PRIVATE);
userid = prefs.getString("userid", null);
currency1 = prefs.getString("currenycode", null);
toolbar = (Toolbar) hostinbox.findViewById(R.id.toolbar);
archive = (ImageView) hostinbox.findViewById(R.id.archive);
alert = (ImageView) hostinbox.findViewById(R.id.alert);
search = (ImageView) hostinbox.findViewById(R.id.search);
blank = (TextView) hostinbox.findViewById(R.id.blank);
host_inbox = (RelativeLayout) hostinbox.findViewById(R.id.host_inbox);
layout.setVisibility(View.INVISIBLE);
start = 1;
final String url = Constants.DETAIL_PAGE_URL + "payment/host_reservation_inbox?userto=" + userid + "&start=" + start + "&common_currency=" + currency1;
//*******************************************ListView code start*****************************************************
System.out.println("url in Inbox page===" + url);
movieList.clear();
JsonObjectRequest movieReq = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener < JSONObject > () {
#SuppressWarnings("deprecation")
#Override
public void onResponse(JSONObject response) {
// progressBar.setVisibility(View.GONE);
// Parsing json
// for (int i = 0; i < response.length(); i++) {
try {
JSONArray contact = response.getJSONArray("contact");
obj_contact = contact.optJSONObject(0);
login_status1 = obj_contact.getString("Status");
// progressBar.setVisibility(View.VISIBLE);
layout.setVisibility(View.INVISIBLE);
listView.setVisibility(View.VISIBLE);
host_inbox.setBackgroundColor(Color.parseColor("#FFFFFF"));
ListFeed movie = new ListFeed();
for (int i = 0; i < contact.length(); i++) {
JSONObject obj1 = contact.optJSONObject(i);
movie.getuserby(obj1.getString("userby"));
movie.resid(obj1.getString("reservation_id"));
movie.setresidinbox(obj1.getString("reservation_id"));
System.out.println("reservation iddgdsds" + obj1.getString("reservation_id"));
movie.setuserbys(obj1.getString("userby"));
movie.setuserto(obj1.getString("userto"));
movie.setid(obj1.getString("room_id"));
movie.getid1(obj1.getString("id"));
movie.userto(obj1.getString("userto"));
movie.isread(obj1.getString("isread"));
movie.userbyname(obj1.getString("userbyname"));
country_symbol = obj1.getString("currency_code");
Currency c = Currency.getInstance(country_symbol);
country_symbol = c.getSymbol();
movie.setsymbol(country_symbol);
movie.setTitle(obj1.getString("title"));
movie.setThumbnailUrl(obj1.getString("profile_pic"));
movie.setstatus(obj1.getString("status"));
movie.setcheckin(obj1.getString("checkin"));
movie.setcheckout(obj1.getString("checkout"));
movie.setcreated(obj1.getString("created"));
movie.guest(obj1.getString("guest"));
movie.userbyname(obj1.getString("username"));
movie.getprice(obj1.getString("price"));
String msg = obj1.getString("message");
msg = msg.replaceAll("<b>You have a new contact request from ", "");
msg = msg.replaceAll("</b><br><br", "");
msg = msg.replaceAll("\\w*\\>", "");
movie.message(msg);
movieList.add(movie);
System.out.println(movieList.get(i).message()); // returning unique values
adapter.notifyDataSetChanged();
}
}
} catch (JSONException e) {
e.printStackTrace();
// progressBar.setVisibility(View.GONE);
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
stopAnim();
//progressBar.setVisibility(View.GONE);
if (error instanceof NoConnectionError) {
Toast.makeText(getActivity(),
"Check your Internet Connection",
Toast.LENGTH_LONG).show();
}
//progressBar.setVisibility(View.GONE);
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
movieReq.setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
return hostinbox;
}
#Override
public void onStop() {
Log.w(TAG, "App stopped");
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public boolean isOnline(Context c) {
ConnectivityManager cm = (ConnectivityManager) c
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return ni != null && ni.isConnected();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
In the above code , System.out.println(movieList.get(i).message()); returning unique values without any problem.
Inboxhostadapter.java = This is the adapter for recycleview
public class InboxHostAdapter extends RecyclerView.Adapter < InboxHostAdapter.CustomViewHolder > {
private List < ListFeed > feedItemList;
private ListFeed listFeed = new ListFeed();
String userid = "",
tag,
str_currency;
String reservation_id,
Liveurl,
india2 = "0";
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
String currency1;
String status1;
//private Activity activity;
public Context activity;
public InboxHostAdapter(Context activity, List < ListFeed > feedItemList, String tag) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
Liveurl = sharedPreferences.getString("liveurl", null);
userid = sharedPreferences.getString("userid", null);
currency1 = sharedPreferences.getString("currenycode", null);
this.feedItemList = feedItemList; // returning duplicate items
this.activity = activity;
listFeed = new ListFeed();
this.tag = tag;
SharedPreferences prefs1 = activity.getSharedPreferences(Constants.MY_PREFS_LANGUAGE, MODE_PRIVATE);
str_currency = prefs1.getString("currencysymbol", null);
if (str_currency == null) {
str_currency = "$";
}
}
#Override
public InboxHostAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hostinbox, parent, false);
FontChangeCrawler fontChanger = new FontChangeCrawler(activity.getAssets(), activity.getString(R.string.app_font_light));
fontChanger.replaceFonts((ViewGroup) view);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(InboxHostAdapter.CustomViewHolder holder, int position) {
// This block returning duplicate items
listFeed = feedItemList.get(position); // This list feedItemList returning duplicate items
reservation_id = listFeed.getid();
System.out.println("reservation id after getting in inbox adapter" + reservation_id);
System.out.println("check out after getting" + listFeed.getcheckout());
System.out.println("message after getting in inbox adapter" + listFeed.getTitle());
System.out.println("symbol after getting" + listFeed.getsymbol());
System.out.println("username after getting" + listFeed.getaddress());
System.out.println("price after getting" + listFeed.getprice());
System.out.println("status after getting" + listFeed.getstatus());
System.out.println("check in after getting" + listFeed.getcheckin());
System.out.println("check out after getting" + listFeed.getcheckout());
System.out.println("userby after getting====" + listFeed.getuserby());
System.out.println("message after getting====" + listFeed.message());
String msg;
msg = listFeed.message();
holder.name.setText(listFeed.userbyname());
holder.time.setText(listFeed.getcreated());
holder.date1.setText(listFeed.getcheckin());
holder.date2.setText(listFeed.getcheckout());
if (listFeed.guest().equals("1")) {
holder.guest.setText(listFeed.guest() + activity.getResources().getString(R.string.guests));
} else {
holder.guest.setText(listFeed.guest() + activity.getResources().getString(R.string.guests));
}
if (tag.equals("Listinbox_service_host")) {
holder.guest.setText("");
holder.ttt.setVisibility(View.INVISIBLE);
} else {
holder.guest.setText(listFeed.guest() + activity.getResources().getString(R.string.guests));
}
// holder.status.setText(listFeed.getstatus());
holder.title.setText(listFeed.getTitle());
status1 = listFeed.getstatus();
if (status1.equals("Accepted")) {
holder.status.setText(activity.getResources().getString(R.string.accepted_details));
}
} else if (status1.equals("Contact Host")) {
holder.status.setText(activity.getResources().getString(R.string.Contact_Host));
holder.guestmsg.setText(listFeed.message());
} else {
holder.status.setText(status1);
}
if (currency1 == null) {
currency1 = "$";
}
if (listFeed.getprice() != null && !listFeed.getprice().equals("null")) {
DecimalFormat money = new DecimalFormat("00.00");
money.setRoundingMode(RoundingMode.UP);
india2 = money.format(new Double(listFeed.getprice()));
holder.currency.setText(listFeed.getsymbol() + " " + india2);
holder.currency.addTextChangedListener(new NumberTextWatcher(holder.currency));
}
//view.imgViewFlag.setImageResource(listFlag.get(position));
System.out.println("listview price" + listFeed.getprice());
System.out.println("listview useds" + listFeed.getresidinbox());
System.out.println("listview dffdd" + listFeed.getuserbys());
System.out.println("listview dfffdgjf" + listFeed.getuserto());
//holder.bucket.setTag(position);
System.out.println("Activity name" + tag);
holder.inbox.setTag(position);
holder.inbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = (int) v.getTag();
Intent search = new Intent(activity, Inbox_detailshost.class);
search.putExtra("userid", userid);
search.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(search);
System.out.println("listview useds" + listFeed.getresidinbox());
System.out.println("listview dffdd" + listFeed.getuserbys());
System.out.println("listview dfffdgjf" + listFeed.getuserto());
}
});
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public int getItemCount() {
System.out.println("list item size" + feedItemList.size());
return (null != feedItemList ? feedItemList.size() : 0);
}
#Override
public int getItemViewType(int position) {
return position;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
ImageView thumbNail;
TextView name, time, date1, date2, currency, guest, status, title, ttt, guestmsg;
RelativeLayout inbox;
CustomViewHolder(View view) {
super(view);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
this.thumbNail = (ImageView) view.findViewById(R.id.list_image);
this.name = (TextView) view.findViewById(R.id.title2);
this.time = (TextView) view.findViewById(R.id.TextView4);
this.date1 = (TextView) view.findViewById(R.id.TextView2);
this.date2 = (TextView) view.findViewById(R.id.TextView22);
this.currency = (TextView) view.findViewById(R.id.TextView23);
this.guest = (TextView) view.findViewById(R.id.TextView25);
this.ttt = (TextView) view.findViewById(R.id.TextView24);
this.status = (TextView) view.findViewById(R.id.TextView26);
this.title = (TextView) view.findViewById(R.id.TextView28);
this.inbox = (RelativeLayout) view.findViewById(R.id.inbox);
this.guestmsg = (TextView) view.findViewById(R.id.guestmessage);
}
}
public class NumberTextWatcher implements TextWatcher {
private DecimalFormat df;
private DecimalFormat dfnd;
private boolean hasFractionalPart;
private TextView et;
public NumberTextWatcher(TextView et) {
df = new DecimalFormat("#,###");
df.setDecimalSeparatorAlwaysShown(true);
dfnd = new DecimalFormat("#,###.##");
this.et = et;
hasFractionalPart = false;
}
#SuppressWarnings("unused")
private static final String TAG = "NumberTextWatcher";
#Override
public void afterTextChanged(Editable s) {
et.removeTextChangedListener(this);
try {
int inilen, endlen;
inilen = et.getText().length();
String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
Number n = df.parse(v);
int cp = et.getSelectionStart();
if (hasFractionalPart) {
et.setText(df.format(n));
} else {
et.setText(dfnd.format(n));
}
endlen = et.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= et.getText().length()) {
et.setSelected(true);
}
} catch (NumberFormatException nfe) {
// do nothing?
} catch (ParseException e) {
// do nothing?
}
et.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator()))) {
hasFractionalPart = true;
} else {
hasFractionalPart = false;
}
}
}
}
In the above code , feedItemList returning duplicate values eventhogh the movieList list from source clas Inboxfragment.java contains unique values.
Kindly please help me with this issue. I tried many answers in Stackoverflow but I can't get solutions. I can't figure out the problem.
Use this code
for (int i = 0; i < contact.length(); i++) {
JSONObject obj1 = contact.optJSONObject(i);
ListFeed movie = new ListFeed();
movie.getuserby(obj1.getString("userby"));
movie.resid(obj1.getString("reservation_id"));
movie.setresidinbox(obj1.getString("reservation_id"));
System.out.println("reservation iddgdsds" + obj1.getString("reservation_id"));
movie.setuserbys(obj1.getString("userby"));
movie.setuserto(obj1.getString("userto"));
movie.setid(obj1.getString("room_id"));
movie.getid1(obj1.getString("id"));
movie.userto(obj1.getString("userto"));
movie.isread(obj1.getString("isread"));
movie.userbyname(obj1.getString("userbyname"));
country_symbol = obj1.getString("currency_code");
Currency c = Currency.getInstance(country_symbol);
country_symbol = c.getSymbol();
movie.setsymbol(country_symbol);
movie.setTitle(obj1.getString("title"));
movie.setThumbnailUrl(obj1.getString("profile_pic"));
movie.setstatus(obj1.getString("status"));
movie.setcheckin(obj1.getString("checkin"));
movie.setcheckout(obj1.getString("checkout"));
movie.setcreated(obj1.getString("created"));
movie.guest(obj1.getString("guest"));
movie.userbyname(obj1.getString("username"));
movie.getprice(obj1.getString("price"));
String msg = obj1.getString("message");
msg = msg.replaceAll("<b>You have a new contact request from ", "");
msg = msg.replaceAll("</b><br><br", "");
msg = msg.replaceAll("\\w*\\>", "");
movie.message(msg);
movieList.add(movie);
System.out.println(movieList.get(i).message()); // returning unique value
}
Declare ListFeed movie = new ListFeed(); into the for Loop
And remove the adapter.notifyDataSetChanged(); from for Loop.
I think this help you.
I am trying to do a search such that all the "visible" search letters should be highlighted. I tried using spannable but that didn't do the trick, maybe I wasnt doing it right? based on this: Highlight searched text in ListView items
How do i get to highlight the visible text? here's my filter :
private LayoutInflater mInflater;
private ValueFilter valueFilter;
public MySimpleArrayAdapter(Activity context) {
this.context = context;
mInflater = LayoutInflater.from(context);
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
#Override
protected synchronized FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Integer> filterList = new ArrayList<>();
int iCnt = listItemsHolder.Names.size();
for (int i = 0; i < iCnt; i++) {
if(listItemsHolder.Types.get(i).toString().indexOf("HEADER_")>-1){
continue;
}
if (listItemsHolder.Names.get(i).matches(getRegEx(constraint))||(listItemsHolder.Names.get(i).toLowerCase().contains(constraint.toString().toLowerCase()))) {
if(filterList.contains(i))
continue;
filterList.add(i);
}
}
results.count = filterList.size();
results.values = filterList;
}else {
String prefixString = getRegEx(constraint);
mSearchText = prefixString;
results.count = listItemsHolder.Names.size();
ArrayList<Integer> tList = new ArrayList<>();
for(int i=0;i<results.count;i++){
tList.add(i);
}
results.values = tList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<Integer> resultsList = (ArrayList<Integer>)results.values;
if(resultsList != null) {
m_filterList = resultsList;
}
notifyDataSetChanged();
}
}
public String getRegEx(CharSequence elements){
String result = "(?i).*";
for(String element : elements.toString().split("\\s")){
result += element + ".*";
}
result += ".*";
return result;
}
Thanks in advance!
Here's my getview
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder holder;
if(filtering && m_filterList != null && m_filterList.size() > position)
position = m_filterList.get(position);
if (rowView == null) {
holder = new ViewHolder();
mInflater = context.getLayoutInflater();
rowView = mInflater.inflate(R.layout.rowlayout, null);
// configure view holder
holder.text = (TextView) rowView.findViewById(R.id.label);
holder.text.setTextColor(Color.WHITE);
holder.text.setSingleLine();
holder.text.setTextSize(15);
holder.text.setEllipsize(TextUtils.TruncateAt.END);
holder.text.setPadding(2, 2, 6, 2);
Typeface label = Typeface.createFromAsset(holder.text.getContext().getAssets(),
"fonts/arial-bold.ttf");
holder.text.setTypeface(label);
holder.image = (ImageView) rowView.findViewById(R.id.icon);
holder.image.setPadding(6, 4, 0, 4);
holder.image.getLayoutParams().height = (int) getResources().getDimension(R.dimen.icon_width_height);
holder.image.getLayoutParams().width = (int) getResources().getDimension(R.dimen.icon_width_height);
rowView.setBackgroundResource(R.drawable.row_border);
rowView.setPadding(2, 2, 6, 2);
rowView.setTag(holder);
}else {
// fill data
holder = (ViewHolder) rowView.getTag();
}
String id = listItemsHolder.getid(position);
String name = listItemsHolder.getName(position);
holder.image.setVisibility(View.VISIBLE);
if (name != null) {
holder.text.setText(listItemsHolder.getName(position));
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) holder.text.getLayoutParams();
params.leftMargin = 20;
}else{
holder.text.setText(id);
}
String fullText = listItemsHolder.getName(position);
// highlight search text
if (mSearchText != null && !mSearchText.isEmpty()) {
int startPos = fullText.toLowerCase(Locale.US).indexOf(mSearchText.toLowerCase(Locale.US));
int endPos = startPos + mSearchText.length();
if (startPos != -1) {
Spannable spannable = new SpannableString(fullText);
ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE});
TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);
spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.text.setText(spannable);
} else {
holder.text.setText(fullText);
}
} else {
holder.text.setText(fullText);
}
return rowView;
}
Let's assume you have create a custom adapter, then you can refer to the following code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
TextView text;
if (convertView == null) {
view = mInflater.inflate(mResource, parent, false);
} else {
view = convertView;
}
try {
if (mFieldId == 0) {
// If no custom field is assigned, assume the whole resource is a TextView
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
text = (TextView) view.findViewById(mFieldId);
}
} catch (ClassCastException e) {
Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
throw new IllegalStateException(
"ArrayAdapter requires the resource ID to be a TextView", e);
}
String item = getItem(position);
text.setText(item);
String fullText = getItem(position);
// highlight search text
if (mSearchText != null && !mSearchText.isEmpty()) {
int startPos = fullText.toLowerCase(Locale.US).indexOf(mSearchText.toLowerCase(Locale.US));
int endPos = startPos + mSearchText.length();
if (startPos != -1) {
Spannable spannable = new SpannableString(fullText);
ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE});
TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);
spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setText(spannable);
} else {
text.setText(fullText);
}
} else {
text.setText(fullText);
}
return view;
}
The mSearchText will be updated at the following inside performFiltering of ArrayFilter class.
String prefixString = prefix.toString().toLowerCase();
mSearchText = prefixString;
You can find more details in my sample code here or my GitHub (with lastest update).
Here is the screenshot
In your filter method, store the string used to perform the filter:
// Filter Class
public void filter(String searchString) {
this.searchString = searchString;
...
// Filtering stuff as normal.
}
You must declare a member string to store it:
public class ListViewAdapter extends BaseAdapter {
...
String searchString = "";
...
And, in getView you highlight the search term:
public View getView(final int position, View view, ViewGroup parent) {
...
// Set the results into TextViews
WorldPopulation item = worldpopulationlist.get(position);
holder.rank.setText(item.getRank());
holder.country.setText(item.getCountry());
holder.population.setText(item.getPopulation());
// Find charText in wp
String country = item.getCountry().toLowerCase(Locale.getDefault());
if (country.contains(searchString)) {
Log.e("test", country + " contains: " + searchString);
int startPos = country.indexOf(searchString);
int endPos = startPos + searchString.length();
Spannable spanText = Spannable.Factory.getInstance().newSpannable(holder.country.getText()); // <- EDITED: Use the original string, as `country` has been converted to lowercase.
spanText.setSpan(new ForegroundColorSpan(Color.RED), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.country.setText(spanText, TextView.BufferType.SPANNABLE);
}
...
}
Hope it helps.
Hi on your adapter class ,make a spanneble text and set it to your textview, the below code you can use for reference.
if ("text contains filter value".toLowerCase().contains("filter".toLowerCase())) {
Spannable spanText = Spannable.Factory.getInstance().newSpannable("text contains filter value".toLowerCase());
Matcher matcher = Pattern.compile("filter".toLowerCase())
.matcher("text contains filter value".toLowerCase());
while (matcher.find()) {
spanText.setSpan(new ForegroundColorSpan(Color.RED), matcher.start(),
matcher.start() + "filter".length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
yourTextView.setText(spanText);
}
This is only demo for highlight text, you can implement your self by calling
highlight(searchText, originalText) in filter,
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView text;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
text = (TextView) findViewById(R.id.textView1);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
text.setText(highlight(editText.getText().toString(), text.getText().toString()));
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
public static CharSequence highlight(String search, String originalText) {
String normalizedText = Normalizer.normalize(originalText, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase();
int start = normalizedText.indexOf(search);
if (start <= 0) {
return originalText;
} else {
Spannable highlighted = new SpannableString(originalText);
while (start > 0) {
int spanStart = Math.min(start, originalText.length());
int spanEnd = Math.min(start + search.length(), originalText.length());
highlighted.setSpan(new BackgroundColorSpan(Color.YELLOW), spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
start = normalizedText.indexOf(search, spanEnd);
}
return highlighted;
}
}
}
Put this code before setting text in getview
Spannable wordtoSpan = new SpannableString("Your_text_in_getviews");
wordtoSpan.setSpan(new ForegroundColorSpan(Color.RED), 0, edtFilter
.getText().toString().length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
txt_contact.setText(wordtoSpan);
It can be done in a bit simpler way:
Define custom adapter:
class HighlightAutoCompleteAdapter(context: Context, resource: Int, private val textResId: Int, items: List<String>) :
ArrayAdapter<String>(context, resource, textResId, items) {
private val inflater = LayoutInflater.from(context)
var queryText = ""
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: inflater.inflate(textResId, parent, false)
val textView: TextView = view.findViewById(android.R.id.text1) as TextView
val fullText = getItem(position) as String
// highlight search text
val highlight: Spannable = SpannableString(fullText)
if (queryText.isNotEmpty()) {
val startPos: Int = fullText.toLowerCase(Locale.US).indexOf(queryText.toLowerCase(Locale.US))
val endPos: Int = startPos + queryText.length
if (startPos != -1) {
highlight.setSpan(StyleSpan(BOLD),
startPos,
endPos,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
textView.text = highlight
return view
}
}
Create the adapter and listen to text changes to keep the adapter updated:
val searchEditText: AutoCompleteTextView = view.findViewById(R.id.search_edit_text)
val arrayAdapter = HighlightAutoCompleteAdapter(requireContext(), 0, R.layout.search_complete_item, autoCompletionList)
searchEditText.setAdapter(arrayAdapter)
searchEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
arrayAdapter.queryText = s?.toString() ?: ""
}
override fun afterTextChanged(s: Editable?) {}
})