ListView won't update xamarin - android

So I have this code:
This is the whole SlidingTabFragment.cs
public class SlidingTabsFragment : Fragment
{
private SlidingTabScrollView mSlidingTabScrollView;
private ViewPager mViewPager;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.fragment_sample, container, false);
}
public override void OnViewCreated(View view, Bundle savedInstanceState)
{
mSlidingTabScrollView = view.FindViewById<SlidingTabScrollView>(Resource.Id.sliding_tabs);
mViewPager = view.FindViewById<ViewPager>(Resource.Id.viewpager);
mViewPager.Adapter = new SamplePagerAdapter();
mSlidingTabScrollView.ViewPager = mViewPager;
}
public class SamplePagerAdapter : PagerAdapter
{
List<string> items = new List<string>();
List<string> mItems;
private ArrayAdapter<string> adapter;
public SamplePagerAdapter() : base()
{
items.Add("Élelmiszerek");
items.Add("Receptek");
items.Add("Recept hozzáadása");
items.Add("Bevásárlólista");
items.Add("Előzmények");
return ;
}
public override int Count
{
get { return items.Count; }
}
public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
return view == obj;
}
public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
{
View view = LayoutInflater.From(container.Context).Inflate(Resource.Layout.pager_item, container, false);
container.AddView(view);
int pos = position + 1;
//I'm using a scrollable menu, and if the user is on the first page than this runs. Moving the `if` somehow fixed my problem.
if (pos == 1)
{
var autoCompleteOptions = new string[] { "Sajt", "Tej", "Kecske", "Barátnő", "piros", "alma" };
ArrayAdapter autoCompleteAdapter = new ArrayAdapter(container.Context, Android.Resource.Layout.SimpleDropDownItem1Line, autoCompleteOptions);
AutoCompleteTextView mautoCompleteTextView = view.FindViewById<AutoCompleteTextView>(Resource.Id.autoCompleteTextView1);
mautoCompleteTextView.Adapter = autoCompleteAdapter;
ListView mListView = view.FindViewById<ListView>(Resource.Id.myListView);
LoadData();
mListView.ItemLongClick += MListView_ItemLongClick;
adapter = new ArrayAdapter<string>(container.Context, Android.Resource.Layout.SimpleListItem1, mItems);
mListView.Adapter = adapter;
adapter.NotifyDataSetChanged();
mautoCompleteTextView.Visibility = ViewStates.Visible;
mListView.Visibility = ViewStates.Visible;
}
return view;
}
private void LoadData()
{
mItems = new List<string>();
for (int i = 1; i < 8; i++)
{
mItems.Add("Élelmiszer"+ i);
}
}
private void MListView_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
Console.WriteLine(mItems[e.Position]);
mItems.RemoveAt(e.Position);
adapter.Remove(adapter.GetItem(e.Position));
adapter.NotifyDataSetChanged();
}
public string GetHeaderTitle(int position)
{
return items[position];
}
public override void DestroyItem(ViewGroup container, int position, Java.Lang.Object obj)
{
container.RemoveView((View)obj);
}
}
}
This is the fragment_sample.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layoutTextColor"
android:orientation="vertical" >
<App6.SlidingTabScrollView
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#color/grey" />
</LinearLayout>
//I'm trying to reproduce the problem in a smaller project.
Fixed
And my problem is that the ListView is not updating. i know the Listview is changeing, because if I longclick an item in it I see in the name of the item in the output in visual studio(because of the Console.Writeline in the MListView_ItemLongClick). And if I longclick the same item again it will write out he next item, because the first I clicked got deleted, but the ListView is not refreshing, so it looks like it's still there.

And my problem is that the ListView is not updating. i know the Listview is changeing, because if I longclick an item in it I see in the name of the item in the output in visual studio(because of the Console.Writeline in the MListView_ItemLongClick).
You need to delete items of your adapter instead of removing items directly on original list, please modify your MListView_ItemLongClick like codes below:
private void MListView_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
Console.WriteLine(mItems[e.Position]);
mItems.RemoveAt(e.Position);
//remove the items directly from adapter
adapter.Remove(adapter.GetItem(e.Position));
adapter.NotifyDataSetChanged();
}

Related

TabLayout With WebServices[API]

I am trying to populate a recyclerview inside the Fragment under a TabLayout. Everything seems to be fine, but the data is not actually populated in the recyclerview, while all the content Logs[Log.e();] is working fine. Can anyone relate the issue ?
My Fragment Is Like :
public class SugarLevelReport extends Fragment
{
private ConstraintLayout view_constraintLayout;
private RecyclerView blood_sugar_recyclerView;
private ProgressBar progressBar;
private ArrayList<PatientRecordModel> patientRecordModelArrayList = new ArrayList<PatientRecordModel>();
private RecyclerView.Adapter bloodSugaradapter;
// for intent data
public String patient_id_from_intent, patient_name_from_intent, patient_dob_from_intent, patient_mobile_from_intent, patient_email_from_intent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_sugar_level_report, container, false);
findViewById(view);
return view;
}
public void findViewById(View view)
{
view_constraintLayout = (ConstraintLayout)view.findViewById(R.id.view_constraintLayout);
/*progressBar = (ProgressBar)view.findViewById(R.id.progressBar);*/
blood_sugar_recyclerView = (RecyclerView)view.findViewById(R.id.blood_sugar_recyclerView);
blood_sugar_recyclerView.setHasFixedSize(true);
blood_sugar_recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
bloodSugaradapter = new SugarLevelReportAdapter(getActivity(), patientRecordModelArrayList);
blood_sugar_recyclerView.setAdapter(bloodSugaradapter);
loadData();
}
public void loadData()
{
if(GlobalMethods.isNetworkConnected(getActivity()))
{
String[] names = getResources().getStringArray(R.array.names);
for (int i = 0 ; i < names.length ; i++)
{
PatientRecordModel patientRecordModel = new PatientRecordModel();
patientRecordModel.setPatient_name(names[i]);
// log here is working fine , and its giving correct data
Log.e("patientsName", patientRecordModel.getPatient_name());
patientRecordModelArrayList.add(patientRecordModel);
bloodSugaradapter.notifyDataSetChanged();
}
}
else
{
}
}
Adapter Class
public class SugarLevelReportAdapter extends RecyclerView.Adapter<SugarLevelReportAdapter.SugarLevelReportHolder>{
public Context context;
public ArrayList<PatientRecordModel> patientRecordModelArrayList = new ArrayList<PatientRecordModel>();
public SugarLevelReportAdapter(Context context, ArrayList<PatientRecordModel> patientRecordModelArrayList)
{
this.context = context;
this.patientRecordModelArrayList = patientRecordModelArrayList;
}
#Override
public SugarLevelReportHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sugar_level_report_cardview, parent, false);
SugarLevelReportHolder sugarLevelReportHolder = new SugarLevelReportHolder(view);
return sugarLevelReportHolder;
}
#Override
public void onBindViewHolder(SugarLevelReportHolder holder, int position)
{
PatientRecordModel patientRecordModel = patientRecordModelArrayList.get(position);
Log.e("patient_name",patientRecordModel.getPatient_name());
holder.patient_name_textView.setText(patientRecordModel.getPatient_name());
}
#Override
public int getItemCount()
{
return patientRecordModelArrayList.size();
}
public static class SugarLevelReportHolder extends RecyclerView.ViewHolder
{
public TextView month_textView, date_textView, year_textView;
public TextView patient_name_textView, patient_count_textView, meal_type_textView;
public ImageView overflow_menu_imageView;
public SugarLevelReportHolder(View itemView)
{
super(itemView);
month_textView = (TextView)itemView.findViewById(R.id.month_textView);
date_textView = (TextView)itemView.findViewById(R.id.date_textView);
year_textView = (TextView)itemView.findViewById(R.id.year_textView);
patient_name_textView = (TextView)itemView.findViewById(R.id.patient_name_textView);
patient_count_textView = (TextView)itemView.findViewById(R.id.patient_count_textView);
meal_type_textView = (TextView)itemView.findViewById(R.id.meal_type_textView);
overflow_menu_imageView = (ImageView)itemView.findViewById(R.id.overflow_menu_imageView);
}
}
}
xml code [fragment_sugar_level_report.xml]
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/blood_sugar_recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
android:scrollbarSize="1dp"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp">
</android.support.v7.widget.RecyclerView>
So I had a similar problem on my current project. I cannot tell you why it happens but to solve it you need to move the part for updating data to the adapter.
on your adapter create the following method:
public void updateData(List<PatientRecordModel> list){
patientRecordModelArrayList = list;
notifyDatasetChanged();
}
On you Fragment class when you want to update the data just call
bloodSugaradapter.updateData(patientRecordModel);
On the same it is advisable to load your views onViewCreated instead of onCreateView. Also use a data mapping library such as GSON or or jackson to improve speed and reliability in data mapping.See a comparison here Hope this helps

onCreateView ListView is Empty. Items Missing

Resolved. See singularhum's answer below.
I have a sliding menu option that points to a fragment. This fragment inflates a layout using onCreateView. I update the values of the list in onActivityCreated . Here is my source.
My Listview
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
this.dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault());
this.portfolio = new Portfolio();
this.portfolio.addCompanyNoUpdate("YHOO");
// Specify the fragment layout file for this fragment class
View view = inflater.inflate(R.layout.fragment_stock, container, false);
progressText = (TextView) view.findViewById(R.id.progressTextView);
// Assign our CursorAdapter
adapter = new QuoteAdapter(getActivity(), portfolio.getQuotes());
ListView list = (ListView) view.findViewById(R.id.list);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
return view;
}
Then I have the onActivityCreated just doing an update.
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.update();
}
My Update Class
private void update() {
// If a network connection is available, update the stock information
if (Utils.isNetworkAvailable(getActivity())) {
// Start a custom task that downloads the data on another thread so the UI does not lock up
new UpdateQuotesTask().execute(portfolio);
}
else {
// Otherwise display an error message to the user
this.progressText.setText(this.getResources().getString(R.string.no_internet_connection));
}
}
My Adapter
public class QuoteAdapter extends BaseAdapter {
private Context context;
private List<Quote> quotes;
public QuoteAdapter(Context c, List<Quote> quotes) {
this.context = c;
this.quotes = quotes;
}
public void addQuote(Quote q) {
this.quotes.add(q);
}
#Override
public int getCount() {
return this.quotes.size();
}
#Override
public Object getItem(int position) {
return this.quotes.get(position);
}
public long getItemId(int position) {
// We can just return a default value for this adapter
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MiniQuoteView miniQuoteView = new MiniQuoteView(this.context, this.quotes.get(position));
miniQuoteView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.FILL_PARENT, ListView.LayoutParams.WRAP_CONTENT));
return miniQuoteView;
}
public void removeItem(int position) {
this.quotes.remove(position);
}
}
And Finally My XML as the standard listview
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/progressTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/none" />
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:verticalSpacing="2dp"
android:layout_below="#+id/progressTextView" />
</RelativeLayout>
For some reason my Listview turns out to be empty.
See the image.
As you can see the debugger also has some values for the adapter.
Here are the related MiniQuoteView Class and XML
http://pastebin.com/rRpRA30L
http://pastebin.com/YajCCqdJ
I believe your issue is in the fillData method in your MiniQuoteView class.
Your first if statement is:
if (this.quote == null)
but you do not have an else or else if statement for when the quote object is not null.
Then if you look at your second if statement (which reads the quote data and sets to views) inside your first one, it is:
if (this.quote.name != null)
which will never be true because the quote is null within that if. That is why you are not seeing anything in your list view because nothing is being set to be displayed.
So it should be something like this:
if (this.quote == null) {
// displaying your not available message
} else if (this.quote.name != null){
// your code to display the data
}

Adding different types of items a list view

Is there a good tutorial or link that shows how to add different items to a listview?
For example, one with two Text lines and a Check box, another that you just press and and something would pop up. All I have now is every list item is the same two line text view and checkbox...
Or, if there is a way to add 1 row at a time with a different layout through R.layout.xxx?
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.frag_settings, container, false);
mItems = getResources().getStringArray(R.array.setting_items);
mItemDescription = getResources().getStringArray(R.array.setting_item_descriptions);
mItemListView = (ListView) mRoot.findViewById(R.id.lvMainListView);
ArrayAdapter<String> lvRowTitle = new ArrayAdapter<String>(getActivity(),
R.layout.setting_twolinetext_checkbox, R.id.tvRowTitle,
mItems);
mItemListView.setAdapter(lvRowTitle);
ArrayAdapter<String> lvRowDesc = new ArrayAdapter<String>(getActivity(),
R.layout.setting_twolinetext_checkbox, R.id.tvRowDesc,
mItemDescription);
mItemListView.setAdapter(lvRowDesc);
return mRoot;
In my example, the list activity that will display our custom list view is called OptionsActivity, because in my project this activity is going to display the different options my user can set to control my app. There are two list item types, one list item type just has a TextView and the second list item type just has a Button. You can put any widgets you like inside each list item type, but I kept this example simple.
The getItemView method checks to see which list items should be type 1 or type 2. According to my static ints I defined up top, the first 5 list items will be list item type 1, and the last 5 list items will be list item type 2. So if you compile and run this, you will have a ListView that has five items that just contain a button, and then five items that just contain a TextView.
Below is the activity code, the activity xml file, and an xml file for each list item type.
OptionsActivity.java:
public class OptionsActivity extends ListActivity {
private static final int LIST_ITEM_TYPE_1 = 0;
private static final int LIST_ITEM_TYPE_2 = 1;
private static final int LIST_ITEM_TYPE_COUNT = 2;
private static final int LIST_ITEM_COUNT = 10;
// The first five list items will be list item type 1
// and the last five will be list item type 2
private static final int LIST_ITEM_TYPE_1_COUNT = 5;
private MyCustomAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();
for (int i = 0; i < LIST_ITEM_COUNT; i++) {
if (i < LIST_ITEM_TYPE_1_COUNT)
mAdapter.addItem("item type 1");
else
mAdapter.addItem("item type 2");
}
setListAdapter(mAdapter);
}
private class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mData = new ArrayList<String>();
private LayoutInflater mInflater;
public MyCustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
if(position < LIST_ITEM_TYPE_1_COUNT)
return LIST_ITEM_TYPE_1;
else
return LIST_ITEM_TYPE_2;
}
#Override
public int getViewTypeCount() {
return LIST_ITEM_TYPE_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public String getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch(type) {
case LIST_ITEM_TYPE_1:
convertView = mInflater.inflate(R.layout.list_item_type1, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type1_text_view);
break;
case LIST_ITEM_TYPE_2:
convertView = mInflater.inflate(R.layout.list_item_type2, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type2_button);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
}
activity_options.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="#+id/optionsList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
list_item_type_1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type1_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/list_item_type1_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text goes here" />
</LinearLayout>
list_item_type2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type2_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/list_item_type2_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button text goes here" />
</LinearLayout>
You have two possibilities to do that:
Create a Type and check for your type and return the view related to this type.
BaseAdapter has two methods to check different items in it, getItemViewType(int position) and getViewTypeCount(). Do your stuff there.
Check this tutorial:
ListView with multiple rows
You should create your own class extending BaseAdapter. I recommend watching The World of ListView, it will help you understand everything you need to know about working with ListView.
In addition to #LouMorda answer, I'd use some class, with fields that contains info about item and list item type:
public class Item {
private int itemViewType;
private Object tag;
private String title;
public Item(int itemViewType){
this.itemViewType = itemViewType;
}
public int getItemViewType() {
return itemViewType;
}
public void setItemViewType(int itemViewType) {
this.itemViewType = itemViewType;
}
...
}
So using this object gives more flexibility when adding items to the list in different sequences:
public class OptionsActivity extends ListActivity {
private static final int LIST_ITEM_TYPE_1 = 0;
private static final int LIST_ITEM_TYPE_2 = 1;
private ArrayList<String> mItemsSource = new ArrayList<>();
...
#Override
public int getItemViewType(int position) {
return mItemsSource.get(position).getItemViewType();
}
...
}

ListView in a fragment Clickable and on item clicked listener

I have a listview in a fragment here is my current code for it:
public static class AllSectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public AllSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tasks_all,
container, false);
// /////////////////////////////////////////////////////////////////
// Set up all components here:: ie text views , buttons lists etc.//
// that correspond to the layout fragment xml file //
////////////////////////////////////////////////////////////////////
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.fragment_tasks_all_textView);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));
ArrayList<String> arrayList = new ArrayList<String>();
ListView allList = (ListView) rootView
.findViewById(R.id.fragment_tasks_all_list);
MyCustomAdapter mAdapter = new MyCustomAdapter(getActivity(),
arrayList); // Class to populate a ListView with an
// ArrayList
allList.setAdapter(mAdapter);
// Populate array list
for (int i = 0; i < 5; i++) {
arrayList.add(" All Task " + i);
}
mAdapter.notifyDataSetChanged();
return rootView;
}
public void onListItemClick(ListView l, View v, int position, long id) {
System.out.println("pos: "+ position);
}
}
and my layout.xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".TasksActivity$DummySectionFragment" >
<TextView
android:id="#+id/fragment_tasks_all_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/fragment_tasks_all_list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="0.41"
android:cacheColorHint="#00000000"
android:clickable="true"
android:listSelector="#android:color/transparent"
android:transcriptMode="alwaysScroll" >
</ListView>
First of all. how can i make it so that i can click on an item in the list,
and second of all how do i add the onclick listener for it.
Why dont you just use ListFragment:
public static class ArrayListFragment extends ListFragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, Shakespeare.TITLES));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
Use the alternative constructor for ArrayAdapter that allows you to specify a layout file to host your listview:
public ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
I had a similar issue and was resolved by creating a interface with onClick method and implementing it in fragment.
Try do this:
Create a interface:
MyOnViewClickListener.java
public interface MyOnViewClickListener {
public void myOnViewClickListener(View v);
}
In your custom adapter class, create a constructor passing MyOnViewClickListener as argument:
private Context context;
private MyOnViewClickListener itemListener;
private List<String> items;
public MyCustomAdapter(Context context, List<String> items, MyOnViewClickListener itemListener) {
this.itemListener = itemListener;
this.context = context;
this.items = items;
}
Inside getView() method, put:
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.your_row_layout, parent, false);
TextView textView1 = (TextView) row.findViewById(R.id.quizchallenge);
textView1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
itemListener.myOnViewClickListener(v);
}
});
Finally, in your fragment class, implement the new interface:
public class ListFriendFragment extends Fragment implements MyOnViewClickListener {
.
.
.
#Override
public void myOnViewClickListener(View v){
//call your method
quickQuiz();
}
Set up the adapter:
adapter = new MyCustomAdapter(getContext(), myItemsList, MyFragment.this);

Centering the clicked item in listview in Android

I have a list view in left of the screen and on click of the item i want to update a text on the right half of the screen, what i want to do here is that to move the clicked item in center of the listview. Like if the item is on top and i click on it it automatically moves to the center of the list view, how I can do this? Any kind of help will be appreciated.
I have a listview in which 7 items are visible and on startup 4th item will be selected as this is in center of the visible items in listview and if there are n items and whichever item is selected by user will be in center of the visible items in listview. Like i have 10 items and on start 4th is selected and when user selects the 3rd item, nth item from listview should come to index zero and and 3rd will come to position 4. Similarly for every other selected item? Can any one provide a code snippet for this?
Change items order in ListView source Array and then call notifyDataSetChanged() in ListView Adapter
EDIT: Code sample
public class ListAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<ListRowObject> listItems;
public ListAdapter(Activity activity){
this.activity = activity;
listItems = new ArrayList<ListRowObject>();
}
public void addItem(ListRowObject item){
listItems.add(item);
notifyDataSetChanged();
}
public void addItems(ArrayList<ListRowObject> items){
listItems = items;
notifyDataSetChanged();
}
public void clear(){
listItems = null;
listItems = new ArrayList<ListRowObject>();
notifyDataSetChanged();
}
#Override
public int getCount() {
return listItems.size();
}
#Override
public Object getItem(int position) {
return listItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = activity.getLayoutInflater().inflate(R.layout.list_row, null);
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.bgLayout = (LinearLayout) convertView.findViewById(R.id.bgLayout);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
ListRowObject row = listItems.get(position);
if(row.isSelected())
holder.bgLayout.setBackgroundColor(Color.GRAY);
else
holder.bgLayout.setBackgroundColor(Color.WHITE);
holder.text.setText(row.getText());
return convertView;
}
}
//--------
public class ListRowObject {
private String text;
private int positionInList;
private boolean isSelected;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getPositionInList() {
return positionInList;
}
public void setPositionInList(int positionInList) {
this.positionInList = positionInList;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
//------
public class Main extends Activity {
private ListView listView;
private ListAdapter adapter;
private Activity activity;
private ArrayList<ListRowObject> items;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
activity = this;
initializeFormViews();
initializeOnClickEvents();
fillList();
}
private void initializeFormViews(){
listView = (ListView) findViewById(R.id.listView);
}
private void initializeOnClickEvents(){
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(activity, "Pressed " +position, Toast.LENGTH_SHORT).show();
// unselect all rows
for(ListRowObject item : items){
item.setSelected(false);
}
int first = adapterView.getFirstVisiblePosition();
int last = adapterView.getLastVisiblePosition();
int centerPosition = (first + last) / 2;
// change bg for centerPosition row
adapterView.getChildAt(centerPosition).findViewById(R.id.bgLayout).setBackgroundColor(Color.GRAY);
changeItems(position, centerPosition);
}
});
}
private void changeItems(int pressedPosition, int centerPosition){
ListRowObject centerRow = items.get(centerPosition);
ListRowObject pressedRow = items.get(pressedPosition);
pressedRow.setSelected(true);
centerRow.setSelected(false);
items.remove(centerPosition);
items.add(centerPosition, pressedRow);
items.remove(pressedPosition);
items.add(pressedPosition, centerRow);
adapter.clear();
adapter.addItems(items);
}
private void fillList(){
adapter = new ListAdapter(activity);
items = new ArrayList<ListRowObject>();
items = getItems();
for(ListRowObject item : items){
adapter.addItem(item);
}
listView.setAdapter(adapter);
}
private ArrayList<ListRowObject> getItems(){
ArrayList<ListRowObject> result = new ArrayList<ListRowObject>();
for(int i = 0; i < 15; i++){
ListRowObject object = new ListRowObject();
object.setPositionInList(i);
object.setText("Item #" + i);
if(i != 4)
object.setSelected(false);
else
object.setSelected(true);
result.add(object);
}
return result;
}
}
//------
public class ViewHolder {
public TextView text;
public LinearLayout bgLayout;
}
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/bgLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/text"
android:textColor="#000000"
android:textSize="24dp"
android:gravity="center"/>
</LinearLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"/>
</LinearLayout>
when you create ArrayAdapter for your listview you send a ListArray to it.when you want change content .you only change this listArray then when click your item you can change ListArray and call notifyDataSetChanged(); method your adapter.

Categories

Resources