Dynamically adding elements to already created relativelayout - android

In my fragment, I want each custom item in my listview to look as follows:
Name
SetsXReps
[][][][][] ---> array of textviews
[][][][][] ---> array of checkboxes
The number of textviews and checkboxes depends upon the item in the adapter, so I need to create that part dynamically. I am having trouble adding these elements dynamically to my relativelayout that I partially define in my xml. Here is my fragment class followed by my xml for the custom list item. The id for the layout is list_item_exercise_in_workout.
public class WorkoutFragment extends Fragment
{
public static final String EXTRA_ALREADYCREATED_ID = "shake2lift.nickdelnano.com";
private ExAdapter adapter;
private ListView listView;
private ArrayList<Set> sets;
private Workout w;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID workoutId = (UUID) getArguments().getSerializable(EXTRA_ALREADYCREATED_ID);
w = WorkoutMASTER.get(getActivity()).getWorkout(workoutId);
}
public View onCreateView(LayoutInflater inflater, ViewGroup parent,Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_workout, parent, false);
adapter = new ExAdapter(getActivity(), R.layout.fragment_create_workout, R.id.list, sets);
listView.setAdapter(adapter);
return v;
}
public static WorkoutFragment newInstance(UUID workoutId)
{
Bundle args = new Bundle();
args.putSerializable(EXTRA_ALREADYCREATED_ID, workoutId);
WorkoutFragment fragment = new WorkoutFragment();
fragment.setArguments(args);
return fragment;
}
private class ExAdapter extends ArrayAdapter<Set>
{
public ExAdapter(Context c, int resource, int textViewResourceId, ArrayList<Set> sets ) {
super(c, 0, sets);
}
public View getView(final int position, View convertView, ViewGroup parent)
{
//if we werent given a view, inflate one
if(convertView == null)
{
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_exercise_in_workout, null);
}
Set s = getItem(position);
//RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
// RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT );
TextView name = (TextView) convertView.findViewById(R.id.exName);
name.setText(s.getName());
TextView setsReps = (TextView) convertView.findViewById(R.id.setsXreps);
setsReps.setText(s.getSets() + "X" + s.getReps());
CheckBox[] checkBoxes = new CheckBox[s.getSetsInt()];
EditText[] weightBoxes = new EditText[s.getSetsInt()];
//initialize weightBoxes's text to the inputted weight
for(int i = 0; i < weightBoxes.length; i++)
{
//code to add dynamically here
}
return convertView;
}
}
}
and my XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayoutEx"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Name"
android:id="#+id/exName"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="SetsXReps"
android:id="#+id/setsXreps"
android:layout_below="#id/exName"
android:layout_alignParentLeft="true"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button2"
android:layout_below="#+id/setsXreps"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="112dp" />
I appreciate any help or advice.

You need to first get a pointer to your RelativeLayout like this
RelativeLayout container = (RelativeLayout) view.findViewById(R.id.relativeLayoutEx);
Then in your for loop, create the Text Boxes (and Check Boxes) dynamically and add them to the layout:
TextView text = new TextView(getActivity());
text.setText("Hello");
container.addView(text);

Related

change id of elements in a reusable xml layout

i have an xml file that contains a reusable layout that i want to be added when the user clicks a button.
inputs.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add"
android:textColor="#color/text_color_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/edittext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/amount"
android:textColor="#color/text_color_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btn"
app:layout_constraintStart_toEndOf="#+id/textview"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity=""
android:text="#string/category"
android:textColor="#color/text_color_blue"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This layout is loaded into a fragment budgetFragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.fragments.BudgetFrag">
<LinearLayout
android:id="#+id/budget_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="17dp"
android:orientation="vertical">
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="10dp"
app:srcCompat="#android:drawable/ic_input_add"/>
</FrameLayout>
the elements get loaded as I need them to but only one problem, all the elements have the same id which comes from the last element loaded.
private BudgetViewModel mViewModel;
private LinearLayout layout = null;
private TextView textView;
private Button button;
private EditText editText;
private ViewGroup viewGroup;
private View viewer;
private LayoutInflater layoutInflater;
private static String TAG = "BudgetFrag :: ";
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bugdet_fragment, container, false);
viewGroup = container;
return v;
}
public int findUnusedId(LinearLayout layout) {
int fID = 0;
while (layout.findViewById(++fID) != null) ;
return fID;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(BudgetViewModel.class);
// TODO: Use the ViewModel
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FloatingActionButton add_elements = view.findViewById(R.id.floating);
layout = view.findViewById(R.id.budget_layout);
add_elements.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View view = getDialog(getActivity(), layout);
layout.addView(view);
}
});
}
public View getDialog(Context context, final LinearLayout layout) {
layoutInflater = LayoutInflater.from(getContext());
viewer = layoutInflater.inflate(R.layout.buget_input, viewGroup, false);
AlertDialog.Builder b = new AlertDialog.Builder(context);
b.setTitle("Select A Category");
String[] types = {"Food", "Entertainment"};
final String[] selected = {""};
b.setItems(types, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
textView = viewer.findViewById(R.id.textview);
switch (which) {
case 0:
textView.setText("Food");
break;
case 1:
textView.setText("Entertainment");
break;
}
editText = viewer.findViewById(R.id.edittext);
Log.d(TAG, "DialogInterface :: editText :: " + editText.getId());
editText.setId(findUnusedId(layout));
button = viewer.findViewById(R.id.btn);
button.setId(findUnusedId(layout));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "setOnClickListener :: editText :: " + editText.getId());
if(!editText.getText().toString().trim().isEmpty()){
Toast.makeText(getContext(), "textView.getId()", Toast.LENGTH_LONG).show();
Log.d(TAG, "setOnClickListener :: "+ editText.getText().toString());
}
}
});
dialog.dismiss();
}
}).show();
return viewer;
}
the getDialog method is where the action happens.
All three elements have the same id as the last added input layout elements.
the question is how can i make each added input layout is unique to be able to get the edittext data? how do i change the ids dynamically as the elememnts are being added?
ps. the number of input layout that can be added is infinite.
This could be a tricky method to handle this problem. First create instance variable like
ArrayList<RootView> rootViews = new ArrayList(); Then we have to generate our own ID to each Root View and its corresponding child views and put it inside above rootViews list.
Look below :
LinearLayout linearLayout = findViewById(R.id.linear);
TextView textView = linearLayout.findViewById(R.id.tv);
EditText editText = linearLayout.findViewById(R.id.et);
Button button = linearLayout.findViewById(R.id.btn);
int uniqueLinearLayoutId = View.generateViewId();
int uniqueTextViewId = View.generateViewId();
int uniqueFirstEditTextId = View.generateViewId();
int uniqueBtnId = View.generateViewId();
ArrayList<Integer> childViews = new ArrayList<>();
childViews.add(uniqueTextViewId);
childViews.add(uniqueFirstEditTextId);
childViews.add(uniqueBtnId);
rootViews.add(new RootView(uniqueLinearLayoutId,childViews));
Now we have structured our view id's inside rootViews list. So, now we can identify each view as they have unique id's.

Is it possible to add different items into android listview

i have a ListView in my application, i fetch contacts from user phonebook then displays them into ListView, now what i want to do is to add different child views into ListView item based on some condition like my application check each phonebook contact for it's availability on server database and what i want to achieve is to add voice/video call buttons for that particular contact and add invite button for all other contacts that are not available in database.
My condition applies on these three child's of ListView item, voice call button, video call button and invite button and my condition is if user is available in database then i only want to display voice/video call button and hide invite button but if the user is not available then i wan to display invite button and hide audio/video call buttons
ListView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/contacts_listview"/>
</RelativeLayout>
ListView Item
<?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="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:minHeight="?android:attr/listPreferredItemHeight"
android:padding="16dp">
<ImageView
android:id="#+id/contact_item_icon"
android:layout_width="50dp"
android:layout_height="50dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingLeft="16dp">
<TextView
android:id="#+id/contact_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Feel The Light" />
<TextView
android:id="#+id/contact_item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Home" />
</LinearLayout>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user_audio_call_dark"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user_video_call_dark"/>
<Button
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="Invite"
android:background="#drawable/selector_button_green_oval"
android:textColor="#color/white"/>
</LinearLayout>
ContactsFragment
public class ContactsAdapter extends ArrayAdapter<ContactItem> {
private static final String LOG_TAG = ContactsAdapter.class.getSimpleName();
public ContactsAdapter(Activity context, List<ContactItem> contactItems) {
super(context, 0, contactItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ContactItem contactItem = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.contact_list_item, parent, false);
}
ImageView contactImage = (ImageView) convertView.findViewById(R.id.contact_item_icon);
contactImage.setImageResource(contactItem.contactImage);
TextView contactName = (TextView) convertView.findViewById(R.id.contact_item_name);
contactName.setText(contactItem.contactName);
TextView contactNumber = (TextView) convertView.findViewById(R.id.contact_item_number);
contactNumber.setText(contactItem.contactNumber);
return convertView;
}
}
ContactsFragment
public class ContactsListFragment extends Fragment {
private ContactsAdapter contactsAdapter;
public static ContactsListFragment newInstance() {
return new ContactsListFragment();
}
public ContactsListFragment() {
}
ArrayList<String> contactName = new ArrayList<>();
ArrayList<String> contactNumber = new ArrayList<>();
ArrayList<ContactItem> contactsAvailable = new ArrayList<>();
ArrayList<ContactItem> contactsInvite = new ArrayList<>();
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor cursor = getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null
);
String currentNumber = "";
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
number = number.replaceAll(" ", "");
char c = number.charAt(0);
char c1 = number.charAt(1);
String s = Character.toString(c)+Character.toString(c1);
if (s.equals("00")) {
number = number.replaceAll("00", "+");
}
if (number.length() == 12) {
number = "+" + number;
}
if (number.length() == 13) {
if (!currentNumber.equals(number)) {
contactName.add(name);
contactNumber.add(number);
}
}
currentNumber = number;
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_contacts_list, container, false);
QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder();
pagedRequestBuilder.setPage(1);
pagedRequestBuilder.setPerPage(50);
QBUsers.getUsersByLogins(contactNumber, pagedRequestBuilder, new QBEntityCallback<ArrayList<QBUser>>() {
#Override
public void onSuccess(ArrayList<QBUser> qbUsers, Bundle bundle) {
for (int i = 0; i < qbUsers.size(); i++) {
ContactItem contactItem = new ContactItem(qbUsers.get(i).getFullName(), qbUsers.get(i).getLogin(), R.drawable.ic_launcher);
contactsAvailable.add(contactItem);
}
contactsAdapter = new ContactsAdapter(getActivity(), contactsAvailable);
ListView listView = (ListView) rootView.findViewById(R.id.contacts_listview_available);
listView.setAdapter(contactsAdapter);
}
#Override
public void onError(QBResponseException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}
});
return rootView;
}
}
Try this:
Add a boolean flag isAvailableInDB in your ContactItem.java class.
Get contact list from your phonebook and check one by one with your server database.
If a contactItem exist in your database just set flag isAvailableInDB as true oterwise false for that contactItem.
After that add contactItem to ArrayList
Create ContactsAdapter and set it to ListView
Finally, add a condition in your adapter's getView() method to check the contactItem flag isAvailableInDB. If true, show voice/video call button & hide invite button and if false, show invite button & hide voice/video call button.
Give an id to XML button's:
<ImageButton
android:id="#+id/button_voice_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user_audio_call_dark"/>
<ImageButton
android:id="#+id/button_video_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user_video_call_dark"/>
<Button
android:id="#+id/button_invite"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="Invite"
android:background="#drawable/selector_button_green_oval"
android:textColor="#color/white"/>
In your adapter's getView() method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ContactItem contactItem = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.contact_list_item, parent, false);
}
ImageView contactImage = (ImageView) convertView.findViewById(R.id.contact_item_icon);
contactImage.setImageResource(contactItem.contactImage);
TextView contactName = (TextView) convertView.findViewById(R.id.contact_item_name);
contactName.setText(contactItem.contactName);
TextView contactNumber = (TextView) convertView.findViewById(R.id.contact_item_number);
contactNumber.setText(contactItem.contactNumber);
ImageButton buttonVoiceCall= (ImageButton) convertView.findViewById(R.id.button_voice_call);
ImageButton buttonVideoCall= (ImageButton) convertView.findViewById(R.id.button_video_call);
Button buttonVoiceCall= (Button) convertView.findViewById(R.id.button_invite);
if(contactItem.getIsAvailableInDB())
{
buttonVoiceCall.setVisibility(View.VISIBLE);
buttonVideoCall.setVisibility(View.VISIBLE);
buttonInvite.setVisibility(View.GONE);
}
else
{
buttonVoiceCall.setVisibility(View.GONE);
buttonVideoCall.setVisibility(View.GONE);
buttonInvite.setVisibility(View.VISIBLE);
}
return convertView;
}
Hope this will help you~
You could add a flag on the ContactItem class and set it true or false, if it is available in the Database and then set the visibility of the buttons in the adapter according to this flag.

How to make the items in the listview respond to the click on that particular row on the listview

I am displaying a tab and which has two tags Category1 and Category2.
The list gets populated based on the data in the tables for category1 and category2. This works fine but to make the items in the listview respond in a certain way to clicks made on the listview is what I am stuck at. Like for example:
I am trying to make the checkbox become visible and checked when the user long clicks on the particular row in the listview. I am trying to code it but I have no idea where to begin. There aren't questions asked on this topic specifically. Below is the code that I have tried.
FragmentClass
public class CategoryFragment extends Fragment{
private ListView listView;
private String currentTabTag;
private CategoryAdapter1 categoryAdapter1;
private CategoryAdapter2 categoryAdapter2;
private MergeAdapter adapter = new MergeAdapter();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// inflate the layout for this fragment
View view = inflater.inflate(R.layout.activity_category_fragment_list, container, false);
// get references to widgets
listView = (ListView) view.findViewById (R.id.ListView);
// get the current tab
TabHost tabHost = (TabHost) container.getParent().getParent();
currentTabTag = tabHost.getCurrentTabTag();
// refresh the category list view
refreshCategoryList();
listView.setOnItemLongClickListener(this);
// return the view
return view;
}
public void refreshCategoryList() {
// get category list for current tab from database
Context context = getActivity().getApplicationContext();
CategoryDatabase categoryDatabase = new CategoryDatabase(context);
if(currentTabTag.equals("Category 1")) {
ArrayList<Category1> category1ArrayList = categoryDatabase.getAllCategory1(currentTabTag);
// create adapter and set it in the ListView widget
categoryAdapter1 = new Category1Adapter(context, category1ArrayList);
adapter.add(Category1Adapter);
}
else if(currentTabTag.equals("Category 2"))
{
ArrayList<Category2> category2ArrayList = categoryDatabase.getAllCategory2(currentTabTag);
// create adapter and set it in the ListView widget
categoryAdapter2 = new categoryAdapter2(context, category2ArrayList);
adapter.add(categoryAdapter2);
}
listView.setAdapter(adapter);
}
#Override
public void onResume() {
super.onResume();
refreshTaskList();
}
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
ItemsListLayout itemsListLayout = new ItemsListLayout(context);
switch (view.getId()) {
case R.id.listView: {
itemsListLayout.setMyListItems();
Toast.makeText(context,"Why cant I be called?",Toast.LENGTH_SHORT).show();
//registerForContextMenu(view);
}
/*default:
Intent intent = new Intent(context, MyCategoryAddEdit.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.putExtra("categoryId", category.getId());
intent.putExtra("editMode", true);
context.startActivity(intent);
break;*/
}
return false;
}
}
activity_category_fragment_list
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:id="#+id/prescriptorsListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:longClickable="true"
android:descendantFocusability="blocksDescendants">
</ListView>
</LinearLayout>
ItemsListLayout
public class ItemsListLayout extends RelativeLayout implements View.OnCreateContextMenuListener {
private CheckBox completedCheckBox;
private TextView nameTextView;
private TextView notesTextView;
private ListView listView;
private CategoryDatabase categoryDatabase;
private Context context;
public ItemsListLayout(Context context) { // used by Android tools
super(context);
}
public ItemsListLayout(Context context, Prescription p) {
super(context);
// set context and get db object
this.context = context;
categoryDatabase = new CategoryDatabase(context);
// inflate the layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.activity_my_category_items_list_layout, this, true);
// get references to widgets
completedCheckBox = (CheckBox) findViewById(R.id.completedCheckBox);
completedCheckBox.setVisibility(GONE);
nameTextView = (TextView) findViewById(R.id.nameTextView);
notesTextView = (TextView) findViewById(R.id.notesTextView);
//listView = (ListView) findViewById(R.id.listView);
// set listeners
//listView.setOnItemLongClickListener(this);
// set task data on widgets
setCategory1(p);
}
public void setCategory1(setCategory1 p) {
setCategory1 = p;
nameTextView.setText(setCategory1.getCategory1Name());
// Remove the notes if empty
if (setCategory1.getMedicineName().equalsIgnoreCase("")) {
notesTextView.setVisibility(GONE);
}
else {
notesTextView.setText(setCategory1.getDescriptionName());
}
}
/*#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
switch (view.getId()) {
case R.id.prescriptorsListView:
completedCheckBox.setVisibility(VISIBLE);
completedCheckBox.setChecked(true);
break;
default:
Intent intent = new Intent(context, MyCategoryAddEdit.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.putExtra("categoryId", category.getId());
intent.putExtra("editMode", true);
context.startActivity(intent);
break;
}
return false;
}
*/
public void setMyListItems()
{
completedCheckBox = (CheckBox) findViewById(R.id.completedCheckBox);
completedCheckBox.setVisibility(VISIBLE);
completedCheckBox.setChecked(true);
}
#Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo)
{
super.onCreateContextMenu(contextMenu);
//MenuInflater inflater = this.context.
}
}
activity_my_category_items_list_layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayoutTaskItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false">
<CheckBox
android:id="#+id/completedCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:button="#drawable/btn_check"
android:textColor="#ffffff"
android:longClickable="true"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"/>
<TextView
android:id="#+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/completedCheckBox"
android:layout_alignBottom="#+id/completedCheckBox"
android:layout_toRightOf="#+id/completedCheckBox"
android:text=""
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="bold"
android:longClickable="true"
android:focusable="false"
android:clickable="false"
android:textIsSelectable="false"
android:focusableInTouchMode="false"/>
<TextView
android:id="#+id/notesTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/nameTextView"
android:layout_marginTop="-5dp"
android:layout_toRightOf="#+id/completedCheckBox"
android:paddingBottom="7dp"
android:textColor="#android:color/white"
android:textSize="18dp"
android:longClickable="true"
android:focusable="false"
android:clickable="false"
android:textIsSelectable="false"
android:focusableInTouchMode="false"/>
</RelativeLayout>
Any kind of help is appreciated. Especially code snippets if possible :).
I suggest you to read this blog, it has step by step procedure of what exactly you want to achieve. You can even clone the project from github.

How to get selected items in a custom listview to another activity in same custom listview

Am developing an app that take student attendance, i want to get the list of checked the names on "TakeAttendance" when i click a "ViewAttendance" on same custom listview . Please how can i do that?
here is my codes...
The custom view
enter code here
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_firstname"
android:text="Firstname"
android:textSize="11dp"
android:ellipsize="start"
android:lines="3"
android:textColor="#000"
android:textStyle="bold"
android:gravity="center"
android:paddingLeft="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lastname"
android:lines="3"
android:textSize="11dp"
android:textColor="#000"
android:textStyle="bold"
android:gravity="center"
android:paddingLeft="10dp"
android:id="#+id/tv_lastname" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_surname"
android:text="Surname"
android:lines="3"
android:textSize="11sp"
android:textColor="#000"
android:textStyle="bold"
android:gravity="center"
android:paddingRight="80dp"
android:paddingLeft="10dp" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:id="#+id/checkBox"
android:checked="false"
android:focusable="false"
android:background="#color/white" />
The Listview
enter code here
The ListAdapter
enter code herepublic class StudentListAdapter1 extends BaseAdapter {
private Context mContext;
private List mStudentList;
//Constructor
public StudentListAdapter1(Context mContext, List<StudentList> mStudentList) {
this.mContext = mContext;
this.mStudentList = mStudentList;
}
#Override
public int getCount() {
return mStudentList.size();
}
#Override
public Object getItem(int position) {
return mStudentList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(mContext, R.layout.student_take, null);
TextView tvReg_no = (TextView) v.findViewById(R.id.tv_reg_no);
TextView tvFirstname = (TextView) v.findViewById(R.id.tv_firstname);
TextView tvLastname = (TextView) v.findViewById(R.id.tv_lastname);
TextView tvSurname = (TextView) v.findViewById(R.id.tv_surname);
//Set text for TextView
tvReg_no.setText(mStudentList.get(position).getReg_no());
tvFirstname.setText(mStudentList.get(position).getFirstname());
tvLastname.setText(mStudentList.get(position).getLasttname());
tvSurname.setText(mStudentList.get(position).getSurname());
//Save product id to tag
v.setTag(mStudentList.get(position).getId());
return v;
}
}
The Attendance Activity
enter code here protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student_take100);
lvStudentlist= (ListView) findViewById(R.id.listview_studentlist);
mStudentList = new ArrayList<>();
//Add sample data for list
//We can get data from DB, webservice here
mStudentList.add(new StudentList(1, "U11EE1001", "Bargo","S.","Mayafi"));
mStudentList.add(new StudentList(2, "U11EE1002", "Barnsbas","Snake.","Maciji"));
mStudentList.add(new StudentList(3, "U11EE1004", "Adamu","Tanko.","Sadau"));
mStudentList.add(new StudentList(4, "U11EE1005", "Munzali","","Cire Tallafi"));
//Init adapter
adapter = new StudentListAdapter1(getApplicationContext(), mStudentList);
lvStudentlist.setAdapter(adapter);
checkBox = (CheckBox) findViewById(R.id.checkBox);
lvStudentlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Do something
SparseBooleanArray checked = lvStudentlist.getCheckedItemPositions();
ArrayList<String> selectedItems = new ArrayList<>();
for (int i = 0; i < checked.size(); i++) {
// Item position in adapter
position = checked.keyAt(i);
// Add names if it is checked i.e.) == TRUE!
if (checked.valueAt(i))
selectedItems.add((String) adapter.getItem(position));
}
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = selectedItems.get(i);
}
Intent intent = new Intent(getApplicationContext(),
ViewAttendanceActivity.class);
// Create a bundle object
Bundle b = new Bundle();
b.putStringArray("selectedItems", outputStrArr);
// Add the bundle to the intent.
intent.putExtras(b);
// start the ResultActivity
startActivity(intent);
}
});
}
}
The View Attendance Activity
enter code here protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_attendance);
Bundle b = getIntent().getExtras();
String[] resultArr = b.getStringArray("selectedItems");
lvStudentlist= (ListView) findViewById(R.id.listview_studentlist);
adapter = new StudentListAdapter(getApplicationContext(), mStudentList);
lvStudentlist.setAdapter(adapter);
}
}
At first I think you should reuse your items in listview
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView != null) {
v = convertView;
} else {
v = View.inflate(mContext, R.layout.student_take, null);
}
.......
now answer for your question, I think you need to add your selected items to array in lvStudentlist.setOnItemClickListener method and then send it as Intent extra to your next activity. You can send String[] as Intent extra so you have no need to use Bundle.

The specified child already has a parent. You must call removeView() on the child's parent first showing error

When I run my program I get the error E/AndroidRuntime(27275): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. where is the problem??
My list fragment class
package com.zaa.yhgj;
public class HomeFragment extends ListFragment {
private List<ListViewItem> mItems; // ListView items list
View myFragmentView;
ArrayList<View> chart_view = new ArrayList<View>();
List<Integer> onedimen = new ArrayList<Integer>();
List<List> aa = new ArrayList<List>();
///
List<List> statuslistoflist = new ArrayList<List>();
List<String> statusonedimen = new ArrayList<String>();
private List<DialogInterface.OnClickListener> nItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.dashboardlist, container, false);
HashMap<String,Integer> myhash=new HashMap<String, Integer>() ;
myhash.put("Pending",0);
myhash.put("In Progress",0);
myhash.put("Limitation",0);
myhash.put("Needs Research",0);
myhash.put("In Testing",0);
myhash.put("Issue Not Clear",0);
myhash.put("Unassigned",0);
int mainclasssize = Constants.listuserprojectMain.getMainListClass().size();
int[] listsize = new int[mainclasssize];
String[] projectname = new String[mainclasssize];
int[] openissuecount = new int[mainclasssize];
for (int k = 0; k < mainclasssize; k++) {
listsize[k] = Constants.listuserprojectMain.getMainListClass().get(k).getProjectIssue().size();
projectname[k] = Constants.listuserprojectMain.getMainListClass().get(k).getName();
openissuecount[k] = Constants.listuserprojectMain.getMainListClass().get(k).getOpenIssueCount();
}
for (int w = 0; w < mainclasssize; w++) {
onedimen = new ArrayList<Integer>();
for (int x = 0; x < listsize[w]; x++) {
myhash.put(Constants.listuserprojectMain.getMainListClass().get(w).getProjectIssue().get(x).getStatus(),Constants.listuserprojectMain.getMainListClass().get(w).getProjectIssue().get(x).getIssueCount());
}
Set keys = myhash.keySet();
Iterator itr = keys.iterator();
String key;
int value;
while(itr.hasNext())
{
key = (String)itr.next();
onedimen.add((Integer)myhash.get(key));
value = (Integer)myhash.get(key);
// System.out.println(key + " - "+ value);
}
aa.add(onedimen);
statuslistoflist.add(statusonedimen);
}
for (int v = 0; v < aa.size(); v++) {
chart_view.add(openChart(aa.get(v)));
}
mItems = new ArrayList<ListViewItem>();
nItems = new ArrayList<DialogInterface.OnClickListener>();
Resources resources = getResources();
for (int f = 0; f < aa.size(); f++) {
mItems.add(new ListViewItem(projectname[f], openissuecount[f], chart_view.get(f)));
}
nItems.add(new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
// initialize and set the list adapter
setListAdapter(new ListViewDemoAdapter(getActivity(), mItems));
return myFragmentView;
}
private View openChart(List<Integer> chartvaluedd) {
return v;
}
}
my adapter class is
public class ListViewDemoAdapter extends ArrayAdapter {
public ListViewDemoAdapter(Context context, List<ListViewItem> items) {
super(context, R.layout.dashboardlistview_item, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder= new ViewHolder();
if(convertView == null) {
// inflate the GridView item layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.dashboardlistview_item, parent, false);
// initialize the view holder
// viewHolder.ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
viewHolder.graphView = (LinearLayout) convertView.findViewById(R.id.ll_chart);
viewHolder.tvCreateIssue = (TextView) convertView.findViewById(R.id.tvCreateissue);
viewHolder.tvDetails = (TextView) convertView.findViewById(R.id.tv_details);
viewHolder.tvIssue = (TextView) convertView.findViewById(R.id.tv_issues);
viewHolder.tvProjectTitle = (TextView) convertView.findViewById(R.id.tv_projectTitle);
viewHolder.tvOpenIssueCount = (TextView) convertView.findViewById(R.id.tv_openissues);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
// recycle the already inflated view
///error when scrolling graph
viewHolder.graphView.removeAllViews();
}
// update the item view
final ListViewItem item = getItem(position);
viewHolder.tvCreateIssue.setText("Create Issue");
viewHolder.tvProjectTitle.setText(item.title);
viewHolder.graphView.addView(item.chartview);
viewHolder.tvOpenIssueCount.setText("Open Issues "+item.openissuecount);
viewHolder.tvCreateIssue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), item.title, Toast.LENGTH_SHORT).show();
}
});
/////
viewHolder.tvIssue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getContext(),"issue",Toast.LENGTH_LONG).show();
}
});
return convertView;
}
private static class ViewHolder {
// ImageView ivIcon;
LinearLayout graphView;
TextView tvCreateIssue;
TextView tvDetails;
TextView tvProjectTitle;
TextView tvOpenIssueCount;
TextView tvIssue;
}
}
my xml layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<include layout="#layout/top" />
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none" >
</ListView>
</LinearLayout>
my listview item is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center_vertical"
android:background="#color/list_background"
android:padding="5dp"
android:id="#+id/ww"
>
<!-- the innner view - provides the white rectangle -->
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#drawable/frame"
android:id="#+id/jhhh">
<!-- the icon view -->
<TextView
android:id="#+id/tv_projectTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Project name"
android:textSize="16dp"
android:textStyle="bold"
android:layout_centerHorizontal="true"
/>
<LinearLayout android:id="#+id/ll_chart"
android:orientation="vertical"
android:layout_below="#+id/tv_projectTitle"
android:layout_width="wrap_content"
android:layout_height="230dp"
android:background="#ffffff"
android:padding="5dp"
android:scaleType="fitXY" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/ll_chart"
android:id="#+id/tv_openissues"
android:text="Open Issues 24"/>
<LinearLayout
android:layout_width="wrap_content"
android:id="#+id/ll_textview"
android:padding="5dp"
android:layout_alignParentRight="true"
android:layout_below="#id/tv_openissues"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView android:id="#+id/tvCreateissue"
android:drawableLeft="#drawable/bug6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create Issue"
/>
<!-- the description view -->
<TextView android:id="#+id/tv_details"
android:layout_below="#id/tvCreateissue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/bars64"
android:layout_marginLeft="5dp"
android:text="Details"
/>
<TextView android:id="#+id/tv_issues"
android:layout_below="#id/tvCreateissue"
android:layout_marginLeft="5dp"
android:drawableLeft="#drawable/bug6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Issues"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
I might be wrong, but the error seems to reside here:
viewHolder.graphView.addView(item.chartview);
Once the view item.chartview is added to graphView, it has a parent. However ListView is known to call some getView on some positions multiple times for caching.
It would seem that the same view is being added to multiple parents which in return throws the error you get. Before adding the chartview you could try removing it from its parent if it exists:
// Remove from parent (if exists)
ViewGroup parent = item.chartview.getParent();
if (parent != null) {
parent.removeView(item.chartview);
}
// Add to another parent
viewHolder.graphView.addView(item.chartview);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.dashboardlist, container, false);
instead of container use null
(I'm not an android geek but faced the problem before)

Categories

Resources