Horizontal ListViews inside a Vertical ScrollView are running slow - android

i am making an app which is similar to pulse and BBC News app
there are titles and beneath each title there is a horzintally scrolling image and text data
i done the horzintal listview part with this library: http://www.dev-smart.com/archives/34
now everything is fine but the problem is the list is scrolling very slowly in the vertical way (its fine in the horizontal way in each row)
how can i solve this problem?
this is my function that adds the horizontal and the title part to the layout:
public void AddCategory(String CatTitle, List<CItem> ItemList) {
LinearLayout thelayout = (LinearLayout) findViewById(R.id.mainlayout);
HorizontialListView listview = new HorizontialListView(this, null);
listview.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, getPixels(100)));
listview.setBackground(getResources().getDrawable(
R.drawable.categoryitemsbackground));
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
TextView tw;
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ///////////////////////////////////////////DO SOMETHING AFTER
// CLICK PART ////////////////////////////////////////////
tw = (TextView) view.findViewById(R.id.itemtitle);
Toast.makeText(getApplicationContext(),
tw.getText().toString(), Toast.LENGTH_LONG).show();
}
});
CategoryAdapter mycategories = new CategoryAdapter(this,
R.layout.categoryitem, ItemList);
listview.setAdapter(mycategories);
TextView textview=(TextView)getLayoutInflater().inflate(R.layout.categorytitle, null);
textview.setText(CatTitle);
thelayout.addView(textview);
thelayout.addView(listview);
}

In the BBC News app, they are not using HorizontalListView instead they are using Gallery. Please try using it.

Why don't you use view pagers? They works better than Horizontal ListView and they aren't deprecated like Gallery.

Related

Add multiple custom LinearLayouts with Buttons to ListView item

I have a question related to this one.
Someone asked about adding multiple custom LinearLayouts programmatically to ListView item and this is almost what I need to do. In this question the author has TextViews in a LinearLayout. I have a Button (and some others) and when I click on this Button I want to inflate a new LinearLayout under this one with just clicked Button.
How to get current LinearLayout position so I could add new LinearLayout under it? Now I'm adding new LinearLayout at the bottom of the list.
You can do like this
yourListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
//if you want get linearLayout at current position
LinearLayout LINTOP = ((LinearLayout) parent.getChildAt(0));
addLayout(LINTOP);
}
});
add new layout like this under LINTOP
public void addLayout(LinearLayout parent){
LinearLayout newLayout= new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
parent.addView(newLayout, 0, params);
}
First of all, please use RecyclerView instead of ListView
You have a method called getAdapterPosition() which returns the position where the interaction happened. So in the ViewHolder if you so something like
linearLayoutView.setOnClickListener
{
Log.d("Position:"+getAdapterPostion());
}
That would give you the position. (The Above code is in Kotlin btw, so may look a bit different)

Use addView instead of a listView

I'm trying to implement a code where there are multiple items.
I am able to populate the ListView and display all these items but I want to inflate a view onItemClick. Unfortunately, AdapterView does not support addView().
So now I want to use addView() to dynamically add items by traversing an ArrayList<>().
How do I do it?
Basically, I want to display a Custom Keypad layout next to a TextView inside the ListView and update the Value of the TextView
This is what I'm trying to do now.
public class OrderSummary extends Activity {
LinearLayout linearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_summary);
linearLayout = new LinearLayout(this);
View view = View.inflate(this, R.layout.top_bar_layout, null);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
linearLayout.addView(view, params);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(OrderSummary.this, "Clicked", Toast.LENGTH_SHORT).show();
}
});
}
}
What you can do is take a LinearLayout(with orientation set to vertical) instead of a ListView. Then make a custom view for each row, traverse the ArrayList, and then inflate the views and keep adding them to the LinearLayout with addView().
P.S. without the actual code , I cannot tell you how to correct your code.
In your code there is issue where are you adding linearLayout into main container ?

onItemClickListener of ListView not working with RatingBar

I have a list item click listener (onItemClickListener) inside the overridden onViewCreated method of a fragment. The method body is given below:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
final String uname = getActivity().getIntent().getExtras().getString("uname");
list = (ListView) getActivity().findViewById(R.id.drlistforhome);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Doctors doc = rh.drList.get(position);
imgURL = doc.getDrProPic();
docName = doc.getDrName();
jobTitle = doc.getDrJobTitle();
docSpeciality = doc.getDrSpeciality();
docUname = doc.getDrUname();
startActivity(new Intent(getActivity().getApplicationContext(), DoctorsProfileH.class).putExtra("img", imgURL)
.putExtra("name", docName)
.putExtra("title", jobTitle)
.putExtra("speciality", docSpeciality)
.putExtra("uname", uname)
.putExtra("druname", docUname));
}
});
}
The custom list view layout consists of six views: 4 TextViews, an ImageView and a RatingBar. The onItemClickListener was listening to list item clicks until the RatingBar was not added. But now that I have added a RatingBar in my custom layout, the listener wouldn't listen the clicks anymore. I am using a custom adapter to set all the views. Here is my custom adapter:
class TDsAdapter extends ArrayAdapter<Doctors> {
public TDsAdapter(){
super(getActivity().getApplicationContext(),R.layout.custom_list_view,rh.drList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
itemView = inflater.inflate(R.layout.custom_list_view, parent, false);
}
Doctors currentItem = rh.drList.get(position);
TextView drName = (TextView) itemView.findViewById(R.id.drName);
drName.setText(currentItem.getDrName());
TextView drSpeciality = (TextView) itemView.findViewById(R.id.drSpeciality);
drSpeciality.setText(currentItem.getDrSpeciality());
TextView drJobTitle = (TextView) itemView.findViewById(R.id.drJobTitle);
drJobTitle.setText(currentItem.getDrJobTitle());
ImageView drProPic = (ImageView) itemView.findViewById(R.id.drPropic);
Picasso.with(getContext()).load(currentItem.getDrProPic()).into(drProPic);
TextView distence = (TextView) itemView.findViewById(R.id.dis);
distence.setText(currentItem.getDis());
RatingBar rb = (RatingBar) itemView.findViewById(R.id.ratingBar);
rb.setRating((float) 2.5);
return itemView;
}
}
After running the application the list view appears fine with the RatingBar as expected, but the list items are no longer clickable. When I debug the app with a break point inside the listener, that break point never gets executed. What I understand from my very little knowledge about fragments, this is probably because the onViewCreated is expecting all the views to be created first. But as we can see, all the views have successfully been created. How can I fix my problem? Please do not hesitate to ask for more specific information.
you can try with
android:descendantFocusability="blocksDescendants"
in root layout of your custom row item.
Write below code in your activity/fragment
listview.setItemsCanFocus(true);
Also please add in your adapter row layout root,
android:descendantFocusability="blocksDescendants"
ListView's onClick will not work If any row item of list contains a focusable or clickable view.
If you have your RatingBar's android:isIndicator set to false, then the RatingBar is focusable / clickable.
Set this in your RatingBar node in your xml:
android:isIndicator="true"

Android listview getting all items

In android, is it possible to get all items inside the list view. Lets say the list view has multiple rows and only 2 rows are visible on the screen while the rest are accessible using the scroll bar. Each row has a radio button and a text view. Is there a way to get all textview of the rows whose radio button is selected and not just the ones visible on the screen.
Your answer may be:
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
You can use custom list view to show your list items with checkbox & textview.
I happened to have a similar requirement where I had multiple EditText inside a ListView and only few of them were visible on the screen. I needed to get the values of all EditText and not just the ones visible on the screen.
Well if you are using a default Adapter, then the way it will work is it will recycle the old views to create new ones. So there is no way to preserve values of those Views which are not visible.
So the only workaround is to create your own Adapter, maybe something like the following, which will not recycle any views, but every time inflate new ones.
public class ListViewAdapter extends ArrayAdapter {
public ListViewAdapter(Context context, ArrayList<Object> items) {
super(context, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return LayoutInflater.from(getContext()).inflate(R.layout.your_layout_for_list_view_item, parent, false);
}
}
After that, as in above answer Lãng Tử Bị Điên has mentioned, you can check in your java code, if your radio buttons are checked or not, and according to that, selected desired TextViews
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
Hopefully this should do it.. It sure worked in my case!

Using ListView : How to add a header view?

I looke at the ListView API
and I saw the method:
addHeaderView(View v)
What I want to do is to have a layout above the list, is this possible ?
I tried doing something like :
EditText et=new EditText(this);
et.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
et.setInputType(InputType.TYPE_CLASS_TEXT);
addHeaderView(et); //makes app crash
I also tried
setContentView(R.layout.tryview);
but it also make the app crash.
Help is very much appreciated!
Edit : The code for this class is:
public class GroupsActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String your_array_contents[] = {"a","ab","c"};
setListAdapter(new ArrayAdapter<String>(this, R.layout.groups_layout, your_array_contents));
EditText et=new EditText(this);
et.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
et.setInputType(InputType.TYPE_CLASS_TEXT);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lv.setAdapter(new ArrayAdapter<String>(GroupsActivity.this,
android.R.layout.simple_list_item_multiple_choice, your_array_contents));
lv.addHeaderView(et); //makes app crash
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
// Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
//Toast.LENGTH_SHORT).show();
}
});
}
}
You can add as many headers as you like by calling addHeaderView() multiple times. You have to do it before setting the adapter to the list view.
And yes you can add header something like this way:
LayoutInflater inflater = getLayoutInflater();
ViewGroup header = (ViewGroup)inflater.inflate(R.layout.header, myListView, false);
myListView.addHeaderView(header, null, false);
You simply can't use View as a Header of ListView.
Because the view which is being passed in has to be inflated.
Look at my answer at Android ListView addHeaderView() nullPointerException for predefined Views for more info.
EDIT:
Look at this tutorial Android ListView and ListActivity - Tutorial .
EDIT 2: This link is broken Android ListActivity with a header or footer
I found out that inflating the header view as:
inflater.inflate(R.layout.listheader, container, false);
being container the Fragment's ViewGroup, inflates the headerview with a LayoutParam that extends from FragmentLayout but ListView expect it to be a AbsListView.LayoutParams instead.
So, my problem was solved solved by inflating the header view passing the list as container:
ListView list = fragmentview.findViewById(R.id.listview);
View headerView = inflater.inflate(R.layout.listheader, list, false);
then
list.addHeaderView(headerView, null, false);
Kinda late answer but I hope this can help someone

Categories

Resources