ListView order get's mixed up when scrolling - java

I am developing an Android application and I am facing a seemingly well-known problem (I found a lot of similar questions but no answer works for me).
I use a ListView that displays an EditText and 2 TextView by adding an item in an ArrayList each time a user presses the button enter. However when I scroll the ListView the order of the elements changes and I can not fix this problem. I understand that the problem comes from the GetView which is recharged each time and therefore, on the view each item changes position but I do not know how to adjust it.
Thanks for your help.
I have already tried to overload the getViewTypeCount () and getItemViewType functions, I also tried to remove the maximum action in the (if convertView == null) but nothing has fixed my problem.
main_game.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#android:color/black">
<ListView android:id="#+id/MyList" android:layout_height="fill_parent"
android:layout_width="fill_parent" android:descendantFocusability="beforeDescendants">
</ListView>
</LinearLayout>
activity_game.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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: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="com.benjamin.realhacksimulatorgame.Game"
android:background="#android:color/black">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/ll_game_vertical"
android:paddingTop="0sp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/ll_game"
android:paddingTop="0sp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/user_name"
android:text="#string/name_user"
android:textColor="#android:color/holo_green_dark"
android:textSize="15sp"
android:textStyle="bold" />
<EditText
android:id="#+id/editText_game"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/holo_green_dark"
android:backgroundTint="#android:color/holo_green_dark"
android:background="#android:color/transparent"
android:textSize="15sp"
android:layout_marginLeft="10dp"
android:textCursorDrawable="#drawable/color_cursor"
android:inputType="text" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/reponse"
android:layout_below="#+id/editText_game"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="#+id/editText_game"
android:layout_alignEnd="#+id/editText_game"
android:textColor="#android:color/holo_green_dark"/>
</LinearLayout>
</RelativeLayout>
And finally the java class Game.java
package com.benjamin.realhacksimulatorgame;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class Game extends Activity {
//DECLARATION
ListView myList;
private MyAdapter myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_game);
Intent i = getIntent();
myList = (ListView) findViewById(R.id.MyList);
myList.setItemsCanFocus(true);
myAdapter = new MyAdapter();
myList.setAdapter(myAdapter);
}
protected void FonctionTest(String test, ViewHolder holder) {
if (test.equalsIgnoreCase("ls") || test.equalsIgnoreCase("ls "))
holder.caption_text.setText("aucun fichier a affiché");
else if (test.equalsIgnoreCase("mkdir") || test.equalsIgnoreCase("mkdir "))
holder.caption_text.setText("Impossible de creer un fichie pour le moment");
else if (test.equalsIgnoreCase(""))
holder.caption_text.setText("Vous n'avez rien entré");
else if (test.equalsIgnoreCase("a "))
holder.caption_text.setText("lettre a");
else
holder.caption_text.setText("Commande inconnu\n\n\ndesole");
}
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ArrayList myItems = new ArrayList();
public MyAdapter() {
// mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ListItem listItem = new ListItem();
myItems.add(listItem);
notifyDataSetChanged();
}
//GET SIZE LIST
public int getCount() {
return myItems.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
// if (convertView == null || ((ViewHolder)convertView.getTag()).id != holder.caption_edit.getId()) {
if (convertView == null ) {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.activity_game, null);
holder = new ViewHolder();
holder.caption_edit = (EditText) convertView.findViewById(R.id.editText_game);
holder.caption_text = (TextView) convertView.findViewById(R.id.reponse);
holder.caption_name = (TextView) convertView.findViewById(R.id.user_name);
//holder.id = holder.caption_edit.getId();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.caption_edit.setId(position);
//we need to update adapter once we finish with editing
final ViewHolder finalHolder = holder;
holder.caption_edit.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
//FILTER
if (event.getAction()!=KeyEvent.ACTION_DOWN) {
Toast.makeText(Game.this, "le retrun true prend effet" , Toast.LENGTH_LONG).show();
return true;
}
//IF USER CLICK ON ENTER BUTTON
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
//DISABLED OLD EDITTEXT
finalHolder.caption_edit.setEnabled(false);
FonctionTest(finalHolder.caption_edit.getText().toString(), finalHolder);
//NEXT ITEM
final int position = v.getId();
final EditText Caption = (EditText) v;
final TextView Caption_text = (TextView) v;
final TextView Caption_name = (TextView) v;
((ListItem) myItems.get(position)).caption_edit = Caption.getText().toString();
((ListItem) myItems.get(position)).caption_text = Caption.getText().toString();
((ListItem) myItems.get(position)).caption_name = Caption.getText().toString();
//Toast.makeText(Game.this, "Ceci est l'editeur numero " + position, Toast.LENGTH_LONG).show();
//CREATE NEW ITEM
ListItem listItem = new ListItem();
myItems.add(listItem);
}
return true;
}
});
return convertView;
}
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
}
class ViewHolder {
int id;
EditText caption_edit;
TextView caption_text;
TextView caption_name;
}
class ListItem {
int id;
String caption_edit;
String caption_text;
String caption_name;
}
}

Related

The expandable list view is not expanding the list when clicked. I tried to set the clickable but still clicking on list doesn't expand anything

I used an expandable list view in the main layout and then used other two layout. The list_parent includes textfield, so clicking on that textfield it should expand to show the third layout which is the list_child and it also contain a text view.
But the problem is that whenever I click on those texts on the expandable list view in activity_main it doesn't expand. I also tried to set the clickable as true in activity_main and added android:descendantFocusability="blocksDescendants" in the ExpandableListView but it's still not expanding on click.
MainActivity.java
package com.calcounterapplication.demoexlist;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ExpandableListView expandableListView;
List<String> langs;
Map<String, List<String>> topics;
ExpandableListAdapter listAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
fillData();
listAdapter = new MyExListAdapter(this,langs,topics);
expandableListView.setAdapter(listAdapter);
}
public void fillData()
{
langs = new ArrayList<>();
topics = new HashMap<>();
langs.add("Java");
langs.add("C");
List<String> java = new ArrayList<>();
List<String> c = new ArrayList<>();
java.add("Super");
java.add("Encapsulation");
java.add("Methods");
c.add("Procedure");
c.add("Pointers");
c.add("Array");
topics.put(langs.get(0),java);
topics.put(langs.get(1),c);
}
}
MyExListAdapter.java
package com.calcounterapplication.demoexlist;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import java.util.List;
import java.util.Map;
public class MyExListAdapter extends BaseExpandableListAdapter
{
Context context;
List<String> langs;
Map<String, List<String>> topics;
public MyExListAdapter(Context context, List<String> langs, Map<String, List<String>> topics) {
this.context = context;
this.langs = langs;
this.topics = topics;
}
#Override
public int getGroupCount() {
return langs.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return topics.get(langs.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return langs.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return topics.get(langs.get(groupPosition)).get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String lang = (String) getGroup(groupPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_parent,null);
}
TextView txtParent = (TextView) convertView.findViewById(R.id.txtParent);
txtParent.setText(lang);
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String topic = (String) getChild(groupPosition,childPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_child,null);
}
TextView txtChild = (TextView) convertView.findViewById(R.id.txtChild);
txtChild.setText(topic);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:clickable="true"
android:focusable="false"
tools:context=".MainActivity">
<ExpandableListView
android:id="#+id/expandableListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
</RelativeLayout>
list_parent.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txtParent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Large Text" />
</LinearLayout>
list_child.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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Name"
android:id="#+id/txtChild"
android:layout_gravity="center" />
</LinearLayout>

Clickable element of ListView with gridView inside (Android)

I want to make listView element clickable.
When i add gridView inside listView then i cant click on listView element..
How to make listView element clickable when gridView is inside listView?
I try to set focusable, descendantFocusability, clickable...
ProductsFragment.java
package pl.pieczolap.ui.products;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import pl.globoox.pieczolap.R;
import pl.pieczolap.API.getProducts;
import pl.pieczolap.MyGridView;
public class ProductsFragment extends Fragment {
private ProductsViewModel StampViewModel;
ArrayList<String> product_uid_shop = new ArrayList();
ArrayList<String> product_uid_product = new ArrayList();
ArrayList<String> product_name = new ArrayList();
ArrayList<String> product_info = new ArrayList();
ArrayList<String> product_stamps = new ArrayList();
ArrayList<String> product_clientStamps = new ArrayList();
MyGridView gridView_stamps;
ListView listView_products;
SharedPreferences sharedPref;
Integer clientStamps;
Integer needStamps;
ImageView imageView_loadingData;
TextView textView_winner;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
StampViewModel =
ViewModelProviders.of(this).get(ProductsViewModel.class);
View root = inflater.inflate(R.layout.fragment_products, container, false);
// LOAD GIF LOADING IMAGE
imageView_loadingData = root.findViewById(R.id.imageView_loadingData);
Glide.with(root).load(R.drawable.loadingdots).placeholder(R.drawable.loadingdots).into(imageView_loadingData);
listView_products = root.findViewById(R.id.listView_products);
sharedPref = getActivity().getApplicationContext().getSharedPreferences("pl.piecozlap", Context.MODE_PRIVATE);
Bundle arguments = this.getArguments();
String uid_shop = arguments.getString("uid_shop", "none");
// GET ALL STAMPS
Response.Listener<String> responseListenerUserComments = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
int errorCode = jsonResponse.getInt("errorCode");
// CANT CONNECT TO DATABASE
if (errorCode == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity().getApplicationContext());
builder.setMessage("Brak połączenia z bazą danych!").setNegativeButton("PONÓW", null).create().show();
}
// GET STAMP AND PRODUCT INFO
if (errorCode == 2) {
JSONArray products = jsonResponse.getJSONArray("products");
for (int i = 0; i < products.length(); i++) {
JSONObject jsonObject = products.getJSONObject(i);
product_uid_shop.add(jsonObject.getString("uid_shop"));
product_uid_product.add(jsonObject.getString("uid_product"));
product_name.add(jsonObject.getString("name"));
product_info.add(jsonObject.getString("info"));
product_stamps.add(jsonObject.getString("stamps"));
product_clientStamps.add(jsonObject.getString("clientStamps"));
}
// HIDE LOADING GIF
imageView_loadingData.setVisibility(View.INVISIBLE);
ProductsAdapter productsAdapter = new ProductsAdapter();
listView_products.setAdapter(productsAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
getProducts getStamps = new getProducts(sharedPref.getString("uid_client", "none"), uid_shop, responseListenerUserComments);
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
queue.add(getStamps);
return root;
}
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
// LISTVIEW CUSTOMADAPTER
public class ProductsAdapter extends BaseAdapter {
#Override
public int getCount() {
return product_uid_shop.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = getLayoutInflater().inflate(R.layout.customlayout_products, null);
clientStamps = Integer.valueOf(product_clientStamps.get(position));
needStamps = Integer.valueOf(product_stamps.get(position));
TextView textView_product_name = convertView.findViewById(R.id.textView_product_name);
TextView textView_product_info = convertView.findViewById(R.id.textView_product_info);
textView_product_name.setText(String.valueOf(clientStamps));
textView_product_info.setText(product_info.get(position));
// WINNER TEXTVIEW
TextView textView_winner = convertView.findViewById(R.id.textView_winner);
if (clientStamps == needStamps) {
textView_winner.setVisibility(View.VISIBLE);
} else {
textView_winner.setVisibility(View.INVISIBLE);
}
// -------------------- //
// CLICK ON SHOP //
// -------------------- //
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("TAGA", "sasdadsa");
new AlertDialog.Builder(getActivity().getApplicationContext())
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Continue with delete operation
}
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
});
gridView_stamps = convertView.findViewById(R.id.gridView_stamps);
StampsAdapter stampAdapter = new StampsAdapter();
gridView_stamps.setAdapter(stampAdapter);
gridView_stamps.setClickable(false);
return convertView;
}
}
// STAMP GRIDVIEW
// STAMP GRIDVIEW
// STAMP GRIDVIEW
// STAMP GRIDVIEW
public class StampsAdapter extends BaseAdapter {
#Override
public int getCount() {
return needStamps;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = getLayoutInflater().inflate(R.layout.customlayout_onestamp, null);
if (position < clientStamps) {
final ImageView imageView = convertView.findViewById(R.id.imgageView_onestamp);
Picasso.get().load("http://pieczolap.pl/admin/shops/999/stamp.jpg").into(imageView);
}
return convertView;
}
}
}
customlayout_products.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="wrap_content"
android:layout_height="400dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="50dp"
android:background="#drawable/customlayout_shops_background"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:background="#drawable/customlayout_shops_background">
<TextView
android:id="#+id/textView_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Info"
android:textSize="15dp" />
<TextView
android:id="#+id/textView_product_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView_product_name"
android:layout_margin="5dp"
android:text="Info"
android:textSize="10dp" />
</RelativeLayout>
<pl.pieczolap.MyGridView
android:id="#+id/gridView_stamps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:columnWidth="100dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="4"
android:padding="10dp"
android:stretchMode="spacingWidth"
android:verticalSpacing="10dp"
app:layout_constraintTop_toBottomOf="#id/relativeLayout"
tools:ignore="MissingConstraints" />
<TextView
android:id="#+id/textView_winner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:rotation="-6"
android:layout_margin="5dp"
android:textColor="#FF0000"
android:textStyle="bold"
android:text="Zebrano wszystkie!"
android:textSize="30dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_products.xml
<?xml version="1.0" encoding="utf-8"?>
<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:descendantFocusability="blocksDescendants"
android:focusable="true"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView_products"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:divider="#null"
android:focusable="true"
android:clickable="true"
android:dividerHeight="10dp"
android:padding="4dp"
android:layout_marginBottom="70dp"
app:layout_constraintTop_toBottomOf="#+id/button_addShop" />
<ImageView
android:id="#+id/imageView_loadingData"
android:layout_width="350dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Android ListView not scrolling at all

I've a ListView that gets populated from a JSON response.
The results go beyond the screen and whatever I tried the listview won't be scrolling.
Currently the XML looks like the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".DrinkActivity">
<ListView
android:id="#+id/drinkList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:scrollbarSize="3dp"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="vertical"
android:scrollingCache="true"
android:smoothScrollbar="true" />
</LinearLayout>
Adapter which the listview is using:
package com.example.tijn.bartenderapp;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Map;
public class DrinksAdapter extends ArrayAdapter<Drink> {
private Activity activity;
private ArrayList<Drink> drinksArrayList;
private static LayoutInflater inflater = null;
public DrinksAdapter(Activity activity, int textViewResourceId, ArrayList<Drink> _drinksArrayList) {
super(activity, textViewResourceId, _drinksArrayList);
try {
this.activity = activity;
this.drinksArrayList = _drinksArrayList;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
} catch (Exception ex) {
}
}
#Override
public int getCount() {
return drinksArrayList.size();
}
public Drink getItem(Drink position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder {
public TextView display_name;
public TextView ingredient0;
public TextView ingredient1;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
final DrinksAdapter.ViewHolder holder;
try {
if (convertView == null) {
vi = inflater.inflate(R.layout.drinksrow, null);
holder = new DrinksAdapter.ViewHolder();
holder.ingredient0 = (TextView) vi.findViewById(R.id.ingredientName0);
holder.ingredient1 = (TextView) vi.findViewById(R.id.ingredientName1);
vi.setTag(holder);
} else {
holder = (DrinksAdapter.ViewHolder) vi.getTag();
}
Drink d = drinksArrayList.get(position);
holder.ingredient0.setText(d.getName());
StringBuilder ingredients = new StringBuilder();
for (Map.Entry<String, Integer> ingredient : d.getIngredients().entrySet()) {
ingredients.append(" ");
ingredients.append(ingredient.getKey());
ingredients.append(", ");
ingredients.append(Integer.toString(ingredient.getValue()));
ingredients.append("ML \n");
}
holder.ingredient1.setText(ingredients.toString().trim());
} catch (Exception e) {
}
return vi;
}
}
Here is the contents of the drinksrow.xml
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/ingredientName0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/ingredientName1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="92dp"
android:layout_marginTop="40dp"
app:layout_constraintStart_toEndOf="#+id/ingredientName0"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/ingredientName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="40dp"
tools:layout_editor_absoluteY="69dp" />
<TextView
android:id="#+id/ingredientName3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="116dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="192dp" />
</android.support.constraint.ConstraintLayout>
Here is the method that sets the ListView :
#Override
public void processFinish(Object output) {
String jsonString = output.toString();
Gson gson = new Gson();
ArrayList<Drink> drinks = gson.fromJson(jsonString, new TypeToken<List<Drink>>(){}.getType());
final ListView listview = (ListView) findViewById(R.id.drinkList);
final DrinksAdapter adapter = new DrinksAdapter(this, R.layout.drinksrow, drinks);
listview.setAdapter(adapter);
listview.setEnabled(false);
}
Already tried to surround the LinearLayout with a ScrollView.
Anybody got an idea?
listview.setEnabled(false);
This disables scrolling.
Not sure why you want to set it to false.
You can use
<ScrollView
android:layout_width="..."
android:layout_height="...">
<LinearLayout
android:orientation="vertical"
android:layout_width="..."
android:layout_height="...">
I use it, and works.

How to programmatically add CardView to LinearLayout in a RecyclerView

Is it possible to programmatically add a CardViewto a LinearLayout inside a RecyclerView. At present, all the CardViews get added to the RecyclerView, but I want the ones in the screenshot to be added to the LinearLayout instead.
fragment class
public class TabFragmentRV extends android.support.v4.app.Fragment {
RecyclerView mRecyclerView;
public TabFragmentRV() {}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_rv, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
View v = getView();
assert v != null;
mRecyclerView = v.findViewById(R.id.my_recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
super.onActivityCreated(savedInstanceState);
initRVAdapter();
}
private void initRVAdapter(){
List<Object> itemsList = new ArrayList<>();
RVItemsAapter itemsListAdapter = new RVItemsAapter(getContext());
mRecyclerView.setAdapter(itemsListAdapter);
itemsList.add(new RVLineSeparator());
itemsList.add(new SectionHeader("Section E"));
itemsList.add(new SMSmessage("Item E1","Item E1 description"));
itemsList.add(new SMSmessage("Item E2","Item E2 description"));
itemsList.add(new SMSmessage("Item E3","Item E3 description"));
itemsList.add(new SMSmessage("Item E4","Item E4 description"));
itemsList.add(new RVLineSeparator());
itemsListAdapter.setCallSMSFeed(itemsList);
itemsListAdapter.notifyDataSetChanged();
}
}
adapter class
public class RVItemsAapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final static int TYPE_MAINHEADER = 1, TYPE_EXPANDABLE = 2, TYPE_NONEXPANDABLE = 3, TYPE_SECTIONHEADER = 4, TYPE_TABLE = 5, TYPE_SEPARATOR = 6;
private ArrayList callSMSFeed = new ArrayList();
private Context context;
public RVItemsAapter(Context context){this.context=context;}
public void setCallSMSFeed(List<Object> callSMSFeed){
this.callSMSFeed = (ArrayList) callSMSFeed;
}
#Override
public int getItemViewType(int position) {
if (callSMSFeed.get(position) instanceof MainHeader) {
return TYPE_MAINHEADER;
} else if (callSMSFeed.get(position) instanceof Phonecall) {
return TYPE_EXPANDABLE;
} else if (callSMSFeed.get(position) instanceof SMSmessage) {
return TYPE_NONEXPANDABLE;
} else if (callSMSFeed.get(position) instanceof SectionHeader) {
return TYPE_SECTIONHEADER;
} else if (callSMSFeed.get(position) instanceof MyTable) {
return TYPE_TABLE;
} else if (callSMSFeed.get(position) instanceof RVLineSeparator) {
return TYPE_SEPARATOR;
}
throw new IllegalArgumentException("Item at position " + position + " is not an instance of either Phonecall or SMSmessage");
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
int viewType=holder.getItemViewType();
switch (viewType){
case TYPE_MAINHEADER:
MainHeader mainHeader = (MainHeader) callSMSFeed.get(position);
((MHeaderViewHolder)holder).showMHeaderDetails(mainHeader);
break;
case TYPE_EXPANDABLE:
Phonecall call = (Phonecall) callSMSFeed.get(position);
((CallViewHolder)holder).showCallDetails(call);
break;
case TYPE_NONEXPANDABLE:
SMSmessage sms = (SMSmessage) callSMSFeed.get(position);
((SMSViewHolder)holder).showSmsDetails(sms);
break;
case TYPE_SECTIONHEADER:
SectionHeader sectionHeader = (SectionHeader) callSMSFeed.get(position);
((SectionViewHolder)holder).showSectionDetails(sectionHeader);
break;
case TYPE_TABLE:
TableToilets tblToilets = (TableToilets) callSMSFeed.get(position);
((TblViewHolder)holder).showTblDetails(tblToilets);
break;
case TYPE_SEPARATOR:
((SeparatorViewHolder)holder).showSeparatorDetails();
break;
default:
throw new IllegalArgumentException("unexpected viewType: " + viewType);
}
}
#Override
public int getItemCount(){return callSMSFeed.size();}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
int layout;
RecyclerView.ViewHolder viewHolder;
switch (viewType){
case TYPE_MAINHEADER:
layout = R.layout.rv_header;
View mainheaderView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new MHeaderViewHolder(mainheaderView);
break;
case TYPE_EXPANDABLE:
layout = R.layout.cardview_dualline_withexpandability;
View callsView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new CallViewHolder(callsView);
break;
case TYPE_NONEXPANDABLE:
layout = R.layout.cardview_dualline_sansexpandability;
View smsView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SMSViewHolder(smsView);
break;
case TYPE_SECTIONHEADER:
layout = R.layout.sectionheaderforrecyclerview;
View sectionheaderView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SectionViewHolder(sectionheaderView);
break;
case TYPE_TABLE:
layout = R.layout.cardview_tableview_withexpandability;
View tblView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new TblViewHolder(tblView);
break;
case TYPE_SEPARATOR:
layout = R.layout.lineseparatorforrecyclerview;
View separatorView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SeparatorViewHolder(separatorView);
break;
default:
throw new IllegalArgumentException("unexpected viewType: " + viewType);
}
return viewHolder;
}
// First ViewHolder of object type Call
// Reference to the views for each call items to display desired information
public class CallViewHolder extends RecyclerView.ViewHolder {
final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);
private TextView arrowexpandcollapseTextView, callerNameTextView, callTimeTextView;
private LinearLayout llFacilityInformation;
CallViewHolder(View itemView) {
super(itemView);
// Initiate view
arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_cvwithexpandability_arrowexpandcollapse);
callerNameTextView = itemView.findViewById(R.id.tv_cvwithexpandability_title);
callTimeTextView = itemView.findViewById(R.id.tv_cvwithexpandability_subtitle);
llFacilityInformation = itemView.findViewById(R.id.ll_cvwithexpandability_subtitle);
arrowexpandcollapseTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
callerNameTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
llFacilityInformation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
}
void showCallDetails(Phonecall call){
// Attach values for each item
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
arrowexpandcollapseTextView.setTypeface(iconFont);
llFacilityInformation.setVisibility(View.GONE);
String callerName = call.getCallerName();
String callTime = call.getCallTime();
callerNameTextView.setText(callerName);
callTimeTextView.setText(callTime);
}
}
// Third ViewHolder of object type SectionHeader
// Reference to the views for each call items to display desired information
public class SectionViewHolder extends RecyclerView.ViewHolder {
final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);
private LinearLayout llSectionWithCards;
private TextView arrowexpandcollapseTextView, sectionNameTextView;
SectionViewHolder(View itemView) {
super(itemView);
// Initiate view
arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_sectionheaderforrv_expandcollapsearrow);
sectionNameTextView = itemView.findViewById(R.id.tv_sectionheaderforrv_title);
arrowexpandcollapseTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (llSectionWithCards.getVisibility() == View.GONE) {
expandLL(llSectionWithCards, arrowexpandcollapseTextView);
} else {
collapseLL(llSectionWithCards, arrowexpandcollapseTextView);
}
}
});
}
void showSectionDetails(SectionHeader section){
// Attach values for each item
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
arrowexpandcollapseTextView.setTypeface(iconFont);
String sectionName = section.getSectionName();
sectionNameTextView.setText(sectionName);
}
}
// Fifth ViewHolder of object type RVLineSeparator
// Reference to the views for each call items to display desired information
public class SeparatorViewHolder extends RecyclerView.ViewHolder {
private View lSeparator;
SeparatorViewHolder(View itemView) {
super(itemView);
lSeparator = itemView.findViewById(R.id.rv_lineseparator);
}
void showSeparatorDetails(){
TypedValue tValueD = new TypedValue();
context.getTheme().resolveAttribute(R.attr.dividerColor, tValueD, true);
lSeparator.setBackgroundResource(tValueD.resourceId);
}
}
private void expandGroup(final TextView arrowexpandcollapseTextView) {
?
}
private void collapseGroup(final TextView arrowexpandcollapseTextView) {
?
}
private void expandLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
llFacilityInformation.setVisibility(View.VISIBLE);
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_up);
}
private void collapseLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
llFacilityInformation.setVisibility(View.GONE);
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
}
}
section header layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_sectionwithexpandability_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_sectionheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="100">
<TextView
android:id="#+id/tv_sectionheader_expandcollapsearrow"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Large" />
<TextView
android:id="#+id/tv_sectionheader_title"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="#android:style/TextAppearance.Large" />
</LinearLayout>
<!-- I WANT ALL THE CARD VIEWS TO BE ADDED INSIDE THIS LINEARLAYOUT (ll_section_cards) -->
<LinearLayout
android:id="#+id/ll_section_cards"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
RecyclerView layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout_recyclerView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_recyclerview"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
SMSmessage class
public class SMSmessage {
private String senderName, smsContent;
public SMSmessage(String senderName, String smsContent) {
this.senderName = senderName;
this.smsContent = smsContent;
}
public String getSenderName() {
return senderName;
}
public String getSmsContent() {
return smsContent;
}
}
First use one parent layout that is linear layout then in that create child layout which contain any layout like linear or relative then of second module you can create second child layout and in child layout you will use card view and other component like textview or edit text inside the card view
Otherwise constrain layout is best to develop this layout
For example
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_sectionwithexpandability_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_sectionheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="100">
<TextView
android:id="#+id/tv_sectionheader_expandcollapsearrow"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:text="Testing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Large" />
<TextView
android:id="#+id/tv_sectionheader_title"
android:layout_weight="90"
android:layout_width="0dp"
android:text="testing"
android:layout_height="wrap_content"
style="#android:style/TextAppearance.Large" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<!-- I WANT ALL THE CARD VIEWS TO BE ADDED INSIDE THIS LINEARLAYOUT (ll_section_cards) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/ll_section_cards"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/te"
android:layout_weight="90"
android:layout_width="wrap_content"
android:text="testing"
android:layout_height="wrap_content"
style="#android:style/TextAppearance.Large" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</LinearLayout>
EDIT: Your question falls under the XY-Problem : enter link description here
Your entire architecture/pattern doesn't seem to fit right.
You may be able to adjust your code so in the "OnBind" method, you check to see if the next n+1 object is an SMSMessage and add the lot to the linear layout...and somehow have a record that they have already been "bound" to avoid double binding...but then you'd also need to detect when that viewholder is unbound...which all seems like fighting the way the framework wants you to do things.
I'd suggest having the API (or a "local service") convert the API data (preferably using ObjectMapper like JacksonMapper) to a class that looks more like:
import java.util.List;
public class SMSMessageCollection {
private List<SMSMessage> smsMessages;
private String headerText;
private boolean hasStartingRVLine;
private boolean hasEndingRVLine;
public SMSMessageCollection(String headerText, boolean hasStartingRVLine, boolean hasEndingRVLine) {
this.headerText = headerText;
this.hasStartingRVLine = hasStartingRVLine;
this.hasEndingRVLine = hasEndingRVLine;
}
//CUSTOM "ADDER":
public void addSMSMessagesToCollection(List<SMSMessage> smsMessagesToAdd){
this.smsMessages.addAll(smsMessagesToAdd);
}
//GETTER AND SETTER HERE -> OR USE LOMBOK...
}
This class contains a List<SMSMessages> so when the object is being bound in the recycler adapter, you can iterate through the list and add them to the linear layout.
So here is what my Activity would look like...taking the API data and making a list of SMSMessageCollection(s) and then this could be passed to the Adapter with one ViewHolder...
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONArray;
import java.io.IOException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//This would be fetched using say Volley...and the structure should MATCH the class we have made...
//Otherwise...make a "service class" to convert the API response to the SMSMessageCollection
JSONArray apiDataModels = new JSONArray();
// Jackson ObjectMapper will turn the API data in to a List or POJOs...in like two lines.
try {
List<SMSMessageCollection> smsMessageCollections = new ObjectMapper()
.readValue(apiDataModels.toString(),new TypeReference<List<SMSMessageCollection>>(){});
} catch (IOException e) {
e.printStackTrace();
}
}
}
So in the OnBindViewHolder method in the adpater, you can get the List for that section and add them programitcally to the LienarLayout of the ViewHolder being injected.

Android - Expandable list view - child data

I have small application written in android. I have tried to implement ExpandableListView into my main layout, but child data do not exists. Collapse works fine but, no data provided.
I have run debugger and see that my list have data.
Here is my code:
main layout - activity_post_details.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_post_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
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="hedza.com.durmitortourism.PostDetailsActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="center"
android:id="#+id/postDetailsTitleText"
android:textSize="32dp"
android:textStyle="bold"
android:textAlignment="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textSize="16dp"
android:layout_marginTop="18dp"
android:id="#+id/postDescText" />
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:id="#+id/ExplistDetails"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/postGalleryBtn"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/postLocationBtn"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
group_item - expandable_list_group.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">
<TextView
android:id="#+id/listTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textColor="#android:color/black"
android:paddingTop="10dp"
android:paddingBottom="10dp" />
</LinearLayout>
expandable_list_item.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">
<TextView
android:id="#+id/expandedListItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:textColor="#000000"
android:textSize="16dp"
android:paddingBottom="10dp" />
</LinearLayout>
ExpandableListAdapter.class
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
public ExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail)
{
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
#Override
public Object getChild(int listPosition, int expandedListPosition)
{
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_list_item, null);
}
TextView expandedListTextView = (TextView) convertView
.findViewById(R.id.expandedListItem);
expandedListTextView.setText(expandedListText);
return convertView;
}
#Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent)
{
String listTitle = (String) getGroup(listPosition);
if (convertView == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.expandable_list_group, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
PostDetailsActivity.class
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class PostDetailsActivity extends AppCompatActivity {
SharedPreferences languageSharedPreferences;
private TextView postTitleTextView;
private TextView postDescTextView;
private ExpandableListView expandableListView;
private ExpandableListAdapter expandableListAdapter;
private List<String> detailsList;
private HashMap<String, List<String>> expandableListDetail;
private Button galleryBtn;
private Button locationBtn;
String locationJSON = null;
String title = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_details);
// setting icon in the action bar
getSupportActionBar().setDisplayShowTitleEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.mipmap.ic_launcher);
// get postID from post activity bundle
Intent intent = getIntent();
String postID = intent.getStringExtra("postID");
// getting language from shared preferences
languageSharedPreferences = getSharedPreferences("LanguagePreferences",
Context.MODE_PRIVATE);
String language = languageSharedPreferences.getString("lang", "me");
final ArrayList<String> viewPagerImages = new ArrayList<>();
// expandable list details initialization
detailsList = new ArrayList<String>();
expandableListDetail = new HashMap<String, List<String>>();
// initialize elements
postTitleTextView = (TextView) findViewById(R.id.postDetailsTitleText);
postDescTextView = (TextView) findViewById(R.id.postDescText);
expandableListView = (ExpandableListView) findViewById(R.id.ExplistDetails);
galleryBtn = (Button) findViewById(R.id.postGalleryBtn);
locationBtn = (Button) findViewById(R.id.postLocationBtn);
// get data from DB by post id
final PostSQLiteManager postObject = new PostSQLiteManager(getApplicationContext());
postObject.openConnection();
JSONObject posts = postObject.getPostsById(postID);
postObject.close();
try
{
JSONArray array = posts.getJSONArray("DATA");
JSONObject arrayObject = array.getJSONObject(0);
String[] images = arrayObject.getString("IMAGES").split(",");
for(int i = 0; i < images.length; i++){
viewPagerImages.add(images[i]);
}
title = arrayObject.getString("TITLE");
// set properties values
postTitleTextView.setText(arrayObject.getString("TITLE"));
postDescTextView.setText(arrayObject.getString("DESC"));
String postWebsite = arrayObject.getString("WEBSITE");
String postEmail = arrayObject.getString("EMAIL");
String postTelephone = arrayObject.getString("TELEPHONE");
locationJSON = arrayObject.getString("LOCATION");
// handling languages
if(language.contentEquals("me"))
{
detailsList.add("Web Stranica: "+postWebsite);
detailsList.add("Telefon: "+postTelephone);
detailsList.add("E-pošta: "+postEmail);
expandableListDetail.put("Detalji", detailsList);
galleryBtn.setText(R.string.galleryPostME);
locationBtn.setText(R.string.locationPostME);
}
else
{
detailsList.add("Website: "+postWebsite);
detailsList.add("Telephone: "+postTelephone);
detailsList.add("E-mail: "+postEmail);
expandableListDetail.put("Details", detailsList);
galleryBtn.setText(R.string.galleryPostEN);
locationBtn.setText(R.string.locationPostEN);
}
final List<String> listTitles = new ArrayList<>(expandableListDetail.keySet());
// generate list
expandableListAdapter = new ExpandableListAdapter(this, listTitles,
expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
// click on gallery button
galleryBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!viewPagerImages.isEmpty()){
Intent galleryIntent = new Intent(getApplicationContext(), GalleryActivity.class);
galleryIntent.putStringArrayListExtra("images", viewPagerImages);
startActivity(galleryIntent);
}else{
Toast.makeText(getApplicationContext(), "Nema slika", Toast.LENGTH_SHORT)
.show();
}
}
});
// click on location button
locationBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent locationIntent = new Intent(getApplicationContext(), MapActivity.class);
locationIntent.putExtra("location", locationJSON);
locationIntent.putExtra("title", title);
startActivity(locationIntent);
}
});
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
listTitles.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
}
catch(JSONException exception) {
exception.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
super.onCreateOptionsMenu(menu);
languageSharedPreferences = getSharedPreferences("LanguagePreferences",
Context.MODE_PRIVATE);
String language = languageSharedPreferences.getString("lang", "me");
// generate menu and its items
MenuInflater myMenu = getMenuInflater();
myMenu.inflate(R.menu.menu_layout, menu);
// change menu items depending on selected language
switch(language)
{
case "me":
menu.findItem(R.id.languageID).setTitle(R.string.languageME);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutME);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorME);
break;
case "en":
menu.findItem(R.id.languageID).setTitle(R.string.languageEN);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutEN);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorEN);
break;
default:
menu.findItem(R.id.languageID).setTitle(R.string.languageME);
menu.findItem(R.id.aboutID).setTitle(R.string.aboutME);
menu.findItem(R.id.sponsorID).setTitle(R.string.sponsorME);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.languageID:
Intent languageIntent = new Intent(getApplicationContext(), LanguageActivity.class);
startActivity(languageIntent);
return true;
case R.id.aboutID:
Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(aboutIntent);
return true;
case R.id.sponsorID:
Intent sponsorIntent = new Intent(getApplicationContext(), SponsorActivity.class);
startActivity(sponsorIntent);
default:
return true;
}
}
}
Does anyone have an idea what's wrong here?
Thank you in advance.

Categories