Related
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?) {}
})
So I have a for loop to make my listview big enough to not scroll, I used this loop from #HussoM. The Cursor returns 3 rows but the for loop run sometimes 7 times and sometimes 10 times.
class dayAdapter extends CursorAdapter {
public dayAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.day_item, parent, false);
dayAdapterViewHolder viewHolder = new dayAdapterViewHolder();
viewHolder.dayTitle = (TextView) view.findViewById(R.id.dayTitle);
viewHolder.transactionList = (ListView) view.findViewById(R.id.day_list);
view.setTag(viewHolder);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
dayAdapterViewHolder dayAdapterViewHolder = (dayAdapter.dayAdapterViewHolder) view.getTag();
Calendar calendar = Calendar.getInstance();
DatabaseHelper dbHelper = new DatabaseHelper(context);
int day = cursor.getInt(cursor.getColumnIndexOrThrow(dbHelper.COLUMN_DATE_DAY));
calendar.set(year - 1900, month, day);
Date date = new Date(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
DateFormat dateFormat = DateFormat.getDateInstance();
dayAdapterViewHolder.dayTitle.setText(dateFormat.format(date));
DayItemAdapter dayItemAdapter = new DayItemAdapter(context, dbHelper.GetTransactionsInDay(day, month, year));
dayAdapterViewHolder.transactionList.setAdapter(dayItemAdapter);
setListViewHeightBasedOnItemsForDays(dayAdapterViewHolder.transactionList);
}
private class dayAdapterViewHolder {
TextView dayTitle;
ListView transactionList;
}
private class DayItemAdapter extends CursorAdapter {
public DayItemAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.transaction_item, parent, false);
DayAdapterViewHolder viewHolder = new DayAdapterViewHolder();
viewHolder.icon = (ImageView) view.findViewById(R.id.transactionIcon);
viewHolder.amount = (TextView) view.findViewById(R.id.amountText);
viewHolder.category = (TextView) view.findViewById(R.id.categoryText);
view.setTag(viewHolder);
return view;
}
#Override
public void bindView(View view, final Context context, Cursor cursor) {
DatabaseHelper dbHelper = new DatabaseHelper(context);
final Utils utils = new Utils();
DayAdapterViewHolder viewHolder = (DayAdapterViewHolder) view.getTag();
TextView category = viewHolder.category;
final ImageView icon = viewHolder.icon;
final int type = cursor.getInt(cursor.getColumnIndexOrThrow(dbHelper.COLUMN_ENTRY_TYPE));
final int entryCategory = cursor.getInt(cursor.getColumnIndexOrThrow(dbHelper.COLUMN_ENTRY_CATEGORY));
final int entrySubCategory = cursor.getInt(cursor.getColumnIndexOrThrow(dbHelper.COLUMN_ENTRY_SUBCATEGORY));
if (entrySubCategory == -1) {
category.setText(utils.expense_and_incomeCategories(context).get(type).get(entryCategory).getCategoryName());
icon.post(new Runnable() {
#Override
public void run() {
icon.setImageResource(utils.expense_and_incomeCategories(context).get(type).get(entryCategory).getCategoryIcon());
}
});
} else {
category.setText(utils.expense_and_incomeCategories(context).get(type).get(entryCategory).getSubCategories().get(entrySubCategory).getSubCategoryName());
icon.post(new Runnable() {
#Override
public void run() {
icon.setImageResource(utils.expense_and_incomeCategories(context).get(type).get(entryCategory).getSubCategories().get(entrySubCategory).getSubCategoryIcon());
}
});
}
String amountString;
TextView amountText = viewHolder.amount;
double amount = cursor.getDouble(cursor.getColumnIndexOrThrow(dbHelper.COLUMN_AMOUNT));
if (amount > 1000 * 1000) {
String editedAmount;
DecimalFormat df = new DecimalFormat("#.#");
df.setRoundingMode(RoundingMode.HALF_UP);
editedAmount = df.format(amount / (1000 * 1000));
amountString = editedAmount + "Mn";
} else if (amount > 1000) {
String editedAmount;
DecimalFormat df = new DecimalFormat("#.#");
df.setRoundingMode(RoundingMode.HALF_UP);
editedAmount = df.format(amount / (1000));
amountString = editedAmount + "K";
} else {
DecimalFormat df = new DecimalFormat("#.#");
df.setRoundingMode(RoundingMode.HALF_UP);
amountString = df.format(amount);
}
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
amountText.setText(dbHelper.getCountryABV(preferences.getLong("country", 1)) + " " + amountString);
}
private class DayAdapterViewHolder {
ImageView icon;
TextView category;
TextView amount;
}
}
and here's the setListViewHeightBasedOnItems() method
public boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
I am creating an events. Also I am creating time tables. Events are created based on time table id. Dynamic event view I have created to show events.
I have created two tables for this events and time table. And loaded events from database.
Now I have loaded the events from time table witch is enabled. I have set color to time tables. This color I want to show on events with respected time table id.
I tried to load this color using Time table's object.
But I have used for loop so it's showing color of last time table to all events.
How can I set color to event's with respected time table id?
Monday fragment :
public class Mon extends Fragment {
private EventTableHelper mDb;
private Intent i;
private ViewGroup dayplanView;
private int minutesFrom,minutesTo;
private List<EventData> events;
private List<View> list;
private List<TimeTable> tables;
private LayoutInflater inflater;
public boolean editMode;
private RelativeLayout container;
private View eventView;
private TimeTableHelper tableHelper;
int color;
private boolean mCheckFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mon, container, false);
list = new ArrayList<View>();
dayplanView = (ViewGroup) view.findViewById(R.id.hoursRelativeLayout);
showEvents();
mCheckFragment = true;
return view;
}
private void createEvent(LayoutInflater inflater, ViewGroup dayplanView, int fromMinutes, int toMinutes, String title,String location,final int id,int color,String notification) {
eventView = inflater.inflate(R.layout.event_view, dayplanView, false);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) eventView.getLayoutParams();
container = (RelativeLayout) eventView.findViewById(R.id.container);
TextView tvTitle = (TextView) eventView.findViewById(R.id.textViewTitle);
list.add(eventView);
ImageView notify = (ImageView) eventView.findViewById(R.id.notify);
((GradientDrawable) eventView.getBackground()).setColor(color);
tvTitle.setTextColor(Color.parseColor("#FFFFFF"));
if (tvTitle.getParent() != null)
((ViewGroup) tvTitle.getParent()).removeView(tvTitle);
if(notification == null)
{
notify.setVisibility(View.GONE);
}
else {
notify.setVisibility(View.VISIBLE);
}
if(location.equals(""))
{
tvTitle.setText("Event : " + title);
} else {
tvTitle.setText("Event : " + title + " (At : " + location +")");
}
int distance = (toMinutes - fromMinutes);
layoutParams.topMargin = dpToPixels(fromMinutes + 9);
layoutParams.height = dpToPixels(distance);
eventView.setLayoutParams(layoutParams);
dayplanView.addView(eventView);
container.addView(tvTitle);
eventView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
i = new Intent(getActivity(), AddEventActivity.class);
editMode = true;
i.putExtra("EditMode", editMode);
i.putExtra("id", id);
startActivityForResult(i, 1);
}
});
}
public void showEvents()
{
tableHelper = new TimeTableHelper(getActivity());
tables = tableHelper.getAllTables();
for (TimeTable table : tables) {
int tableId = table.getId();
int status = table.getStatus();
if(status == 1) {
color = table.getTableColor();
}
mDb = new EventTableHelper(getActivity());
events = mDb.getTimeTableEvents("Mon", tableId);
}
for (EventData eventData : events) {
int id = eventData.getId();
String datefrom = eventData.getFromDate();
if (datefrom != null) {
String[] times = datefrom.substring(11, 16).split(":");
minutesFrom = Integer.parseInt(times[0]) * 60 + Integer.parseInt(times[1]);
}
String title = eventData.getTitle();
String location = eventData.getLocation();
String dateTo = eventData.getToDate();
String notification = eventData.getNotificationTime();
if (dateTo != null) {
//times = dateTo.substring(11,16).split(":");
String[] times1 = dateTo.substring(11, 16).split(":");
minutesTo = Integer.parseInt(times1[0]) * 60 + Integer.parseInt(times1[1]);
}
createEvent(inflater, dayplanView, minutesFrom, minutesTo, title, location, id, color, notification);
id++;
}
}
public void removeView()
{
for(int i=0; i<list.size(); i++)
{
View view = (View)list.get(i);
dayplanView.removeView(view);
}
}
private int dpToPixels(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density);
}
#Override
public void onResume()
{
super.onResume();
if(mCheckFragment)
{
removeView();
showEvents();
}
}
}
EDIT:
public void showEvents()
{
tableHelper = new TimeTableHelper(getActivity());
tables = tableHelper.getAllTables();
int color = 0;
for (TimeTable table : tables) {
int tableId = table.getId();
int status = table.getStatus();
mDb = new EventTableHelper(getActivity());
events = mDb.getTimeTableEvents("Mon", tableId);
for (EventData eventData : events) {
int id = eventData.getId();
String datefrom = eventData.getFromDate();
if (datefrom != null) {
String[] times = datefrom.substring(11, 16).split(":");
minutesFrom = Integer.parseInt(times[0]) * 60 + Integer.parseInt(times[1]);
}
String title = eventData.getTitle();
String location = eventData.getLocation();
String dateTo = eventData.getToDate();
color = table.getTableColor();
String notification = eventData.getNotificationTime();
if (dateTo != null) {
//times = dateTo.substring(11,16).split(":");
String[] times1 = dateTo.substring(11, 16).split(":");
minutesTo = Integer.parseInt(times1[0]) * 60 + Integer.parseInt(times1[1]);
}
createEvent(inflater, dayplanView, minutesFrom, minutesTo, title, location, id, color, notification);
id++;
}
}
}
Thank you..
Try merging the two for loops together and see if that works..
as well as the color, it also looks like the events are set to the last table when it enters the second for loop.
for(TimeTable table : tables) {
// code from table for loop
// ...
for(EventData eventData : events) {
// code from event for loop.
// ...
}
}
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.
i´m newbie in android programming and try to set two Image Array from (Values)XML in to one common Array using TypedArray.
Here are my XML Arrays:
<array name="Img1">
<item> #drawable/pic_1 </item>
<item> #drawable/pic_2 </item>
<item> #drawable/pic_3 </item>
</array>
<array name="Img2">
<item> #drawable/pic_4 </item>
<item> #drawable/pic_5 </item>
<item> #drawable/pic_6 </item>
</array>
imprtant part of java code in onCreate method:
private TypedArray Images;
TypedArray img1 = res.obtainTypedArray(R.array.Img1);
TypedArray img2 = res.obtainTypedArray(R.array.Img2):
ArrayList<TypedArray> img = new ArrayList<TypedArray>();
img.addAll(Arrays.asList(img1));
img.addAll(Arrays.asList(img2));
Images = img.toArray(new TypedArray(img1.length()+img2.length); <-- NOT WORKING!
what ist wron in my code? maybe i can solve the problem by another way?
Thank you very much!!!
public class c_DTArtikel_allforsearch extends Activity implements AdapterView.OnItemClickListener {
//Variablen deklarieren!
private ListView ListViewLayout;
private String[] Number;
private int[] ImagesID;
private EditText Search;
ArrayList name = new ArrayList();
My method:
private ListView ListViewLayout;
private int[] ImagesID;
private EditText Search;
ArrayList<String> name = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_lv_search);
Resources res = getResources();
String[] saugname = res.getStringArray(R.array.SauglanzeName);
String[] pumpmname = res.getStringArray(R.array.PumpMName);
String[] saugnummer = res.getStringArray(R.array.SauglanzeNumber);
String[] pumpmnummer = res.getStringArray(R.array.PumpMNummer);
TypedArray saugimg = res.obtainTypedArray(R.array.SauglanzeImg);
TypedArray pumpmimg = res.obtainTypedArray(R.array.PumpeMImg);
name.addAll(Arrays.asList(saugname));
name.addAll(Arrays.asList(pumpmname));
ArrayList<String> number = new ArrayList<String>();
number.addAll(Arrays.asList(saugnummer));
number.addAll(Arrays.asList(pumpmnummer));
Number = number.toArray(new String[saugnummer.length+pumpmnummer.length]);
ArrayList<Integer> imgInts = new ArrayList<Integer>();
int nr = -1;
while ( ++nr < saugimg.length() )
imgInts.add (saugimg.getResourceId(nr, 0));
nr = -1;
while ( ++nr < pumpmimg.length() )
imgInts.add (pumpmimg.getResourceId(nr, 0));
ImagesID = new int[imgInts.size()];
for (int i=0; i < imgInts.size(); i++)
{
ImagesID[i] = ((Integer) imgInts.get(i)).intValue();
}
Search = (EditText) findViewById(R.id.EditTextSearch);
ListViewLayout = (ListView) findViewById(R.id.listViewLayoutSearch);
final TIAdapter adapter = new TIAdapter(this, name, ImagesID, Number);
ListViewLayout.setAdapter(adapter);
ListViewLayout.setOnItemClickListener(this);
Search.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
adapter.getFilter().filter(cs);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
class Adapter:
class TIAdapter extends ArrayAdapter<String> {
Context context;
int [] ImagesID;
ArrayList<String> NameArray;
String[] NummerArray;
TIAdapter(Context c, ArrayList<String> Artikel, int[] imgs, String[] Nummer) {
super(c, R.layout.layout_text_image, R.id.textViewArtikel, Artikel);
this.context = c;
this.ImagesID = imgs;
this.NameArray = Artikel;
this.NummerArray = Nummer;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ImageView imageView = null;
if(row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.layout_text_image, parent, false);
imageView = (ImageView)row.findViewById(R.id.imageViewArtikel);
}
else {
imageView = (ImageView)row.findViewById(R.id.imageViewArtikel);
DecodeTask dt1 = (DecodeTask)imageView.getTag(R.id.imageViewArtikel);
if(dt1 != null)
dt1.cancel(true);
}
imageView.setImageBitmap(null);
DecodeTask dt2 = new DecodeTask(getContext(), imageView, ImagesID[position]);
dt2.execute();
TextView textViewArtikel = (TextView) row.findViewById(R.id.textViewArtikel);
TextView textViewArtikelNummer = (TextView) row.findViewById(R.id.textViewArtikelNummer);
imageView.setTag(R.id.imageViewArtikel, dt2);
textViewArtikel.setText(name.get(position));
textViewArtikelNummer.setText(Number[position]);
return row;
}
}
Maybe something like this:
ArrayList<Drawable> img = new ArrayList<Drawable>();
int nr = -1;
while ( ++nr < img1.length() )
img.add( img1.getDrawable(nr));
nr = -1;
while ( ++nr < img2.length() )
img.add( img2.getDrawable(nr));
Drawable [] Images;
Images = img.toArray(new Drawable[img.size()] );
Maybe better to give the adapter an array of resource identifiers (which are Integers).
ArrayList<Integer> imgInts = new ArrayList<Integer>();
int nr = -1;
while ( ++nr < img1.length() )
imgInts.add (img1.getResourceId(nr, 0));
nr = -1;
while ( ++nr < img2.length() )
imgInts.add (img1.getResourceId(nr, 0));
int[] ResourceIds = new int[imgInts.size()];
for (int i=0; i < imgInts.size(); i++)
{
ResourceIds[i] = ((Integer) imgInts.get(i)).intValue();
}
Use ResourceIds as parameter to construct the adapter.