Sorry for my english. I spent meny times try fix my problem, but I could not do it. I have listView, in this list view for some elements create spinner. Spinner created in adapter. I cant get value spinner. Its vary hard from me. Please healp
My adapter
public class ExpListAdapter extends BaseExpandableListAdapter {
private ArrayList<ArrayList<String>> mGroups;
private ArrayList<DeviceObject> deviceObList;
private ArrayList<RoomSuggestion> roObjList;
private Context mContext;
public ExpListAdapter (Context context,ArrayList<ArrayList<String>> groups, ArrayList<DeviceObject> deviceObList, ArrayList<RoomSuggestion> roObjList){
mContext = context;
mGroups = groups;
this.deviceObList = deviceObList;
this.roObjList = roObjList;
}
#Override
public int getGroupCount() {
return mGroups.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return mGroups.get(groupPosition).size();
}
#Override
public Object getGroup(int groupPosition) {
return mGroups.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return mGroups.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 true;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_view, null);
}
if (isExpanded){
//Изменяем что-нибудь, если текущая Group раскрыта
}
else{
//Изменяем что-нибудь, если текущая Group скрыта
}
Typeface lightFace = Typeface.createFromAsset(mContext.getAssets(), "font/GothamProLight.ttf");
TextView textGroup = (TextView) convertView.findViewById(R.id.textGroup);
textGroup.setTypeface(lightFace);
textGroup.setText("Thereses gate 46");
return convertView;
}
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_view, null);
}
Typeface mediumFace = Typeface.createFromAsset(mContext.getAssets(), "font/GothamProMedium.ttf");
TextView textChild = (TextView) convertView.findViewById(R.id.textChild);
textChild.setTypeface(mediumFace);
textChild.setText( mGroups.get(groupPosition).get(childPosition) );
RelativeLayout rl = (RelativeLayout) convertView.findViewById(R.id.bg_button_screen);
if( !deviceObList.get(childPosition).getProduct_id().equals("0") ) {
rl.setBackgroundColor(Color.parseColor("#4fcc54"));
View linearLayoutG = convertView.findViewById(R.id.container);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 0, 10, 30);
linearLayoutG.setLayoutParams(layoutParams);
RelativeLayout spinnerOpen = (RelativeLayout) convertView.findViewById(R.id.spinnerOpen);
View linearLayout = convertView.findViewById(R.id.spinnerL);
ImageView imageS = (ImageView)convertView.findViewById(R.id.spinnerImage);
imageS.getLayoutParams().width = 20;
imageS.getLayoutParams().height = 20;
imageS.setImageResource(R.drawable.spin_ok);
ArrayList<String> list = new ArrayList<String>();
for(int i = 0; i < roObjList.size(); i++) {
list.add(roObjList.get(i).getName() );
}
final Spinner spinner = new Spinner(mContext);
//Make sure you have valid layout parameters.
spinner.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 100));
spinner.setBackgroundResource(R.drawable.bg_spinner);
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(mContext,
R.layout.spinner_item, list);
spinner.setAdapter(spinnerArrayAdapter);
//open spinner
spinnerOpen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.performClick();
}
});
((LinearLayout) linearLayout).addView(spinner);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.e("selected", String.valueOf(parent.getItemAtPosition(position)) );
Log.e("childPosition", String.valueOf(childPosition));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} else {
rl.setBackgroundColor(Color.parseColor("#e5910d"));
}
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
My xml from adapter
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_marginBottom="5dp"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/bgchilddevice"
android:layout_width="match_parent"
android:layout_weight="0.3"
android:layout_marginLeft="5dp"
android:background="#26ffffff"
android:layout_marginRight="2.5dp"
android:layout_height="60dp">
<TextView
android:id="#+id/textChild"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:textSize="18dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/bg_button_screen"
android:layout_weight="0.9"
android:layout_marginRight="5dp"
android:background="#4fcc54"
android:layout_width="match_parent"
android:layout_marginLeft="2.5dp"
android:layout_height="60dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/check"
android:id="#+id/imageView6"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="#26ffffff"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/spinnerL"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_weight="0.2"
android:layout_centerHorizontal="true" />
<RelativeLayout
android:id="#+id/spinnerOpen"
android:layout_width="match_parent"
android:layout_marginRight="5dp"
android:layout_weight="0.8"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/spinnerImage"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
And that i try get spinner elements
create.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0; i < listView.getAdapter().getCount(); i++ ) {
for(int j = 0; j < listView.getChildCount(); j++ ) {
View _mainView = listView.getChildAt(j);
LinearLayout _linearLayout = (LinearLayout) _mainView.findViewById(R.id.spinnerL);
Spinner spinner = (Spinner) _linearLayout.getChildAt(0);
String selection = (String) spinner.getSelectedItem();
Log.e("spinner device", selection);
}
}
}
});
And i have
FATAL EXCEPTION: main java.lang.NullPointerException
in line Spinner spinner = (Spinner) _linearLayout.getChildAt(0);
i try write
Spinner spinner = (Spinner) _linearLayout.getChildAt(0);
Spinner spinner = (Spinner) _linearLayout.getChildAt(1);
Spinner spinner = (Spinner) _linearLayout.getChildAt(2);
Spinner spinner = (Spinner) _linearLayout.getChildAt(3);
its error
Why don't you use findViewById() for the spinner?
Spinner spinner =(Spinner) findViewById(R.id.spinnerL);
String value = spinner.getSelectedItem().toString();
I dont know it bad code or not, i try write like this and its work!!!
for(int j = 0; j < listView.getChildCount(); j++ ) {
View _mainView = listView.getChildAt(j);
LinearLayout _linearLayout = (LinearLayout) _mainView.findViewById(R.id.spinnerL);
try{
Spinner spinner = (Spinner) _linearLayout.getChildAt(0);
String selection = (String) spinner.getSelectedItem();
Log.e("spinner device", selection);
}catch(Exception e){
}
}
Related
I have populated weight conversion functionality on listview using string array. I want to change the values of each entity when new value is typed by the user on any entity i.e KG, Pound and Gram. But addTextChangedListener is not responding properly and values are getting wrong on each EditText.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
convAdapter adapter = new convAdapter(MainActivity.this);
ListView list = findViewById(R.id.unitc_list);
list.setAdapter(adapter);
}
}
convAdapter.java
public class convAdapter extends BaseAdapter {
static TextWatcher watcher=null;
DecimalFormat format = new DecimalFormat("0.########");
private String unitWeight[] = {"Pound","Kilogram","Gram"};
private static String unitWeightValue[] = {"2.204","1","1000"};
private String unitWeightValueUpdated[] = unitWeightValue;
private static Activity activity;
private static LayoutInflater inflater=null;
public convAdapter(Activity a) {
activity = a;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return unitWeight.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
convertView = inflater.inflate(R.layout.unit_row, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txtItem.setText(unitWeight[position]);
viewHolder.etValue.setText(format.format(((double) Math.round(10000*Double.parseDouble(unitWeightValueUpdated[position]))/10000.0)));
viewHolder.txtItem.setTag(position);
viewHolder.etValue.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void afterTextChanged(Editable s) {
if(unitWeight[position].equals("Kilogram")){
int i = 0;
for(String pos: unitWeightValue ){
unitWeightValueUpdated[i] = format.format(((double) Math.round(Double.parseDouble(pos)*Double.parseDouble(String.valueOf(viewHolder.etValue.getText())))));
i++;
}
}else{
int i = 0;
for(String pos: unitWeightValue ) {
unitWeightValueUpdated[i] = String.valueOf(Double.parseDouble(viewHolder.etValue.getText().toString())* Double.parseDouble(pos) /
Double.parseDouble(unitWeightValueUpdated[i]));
i++;
}
}
}
});
return convertView;
}
private class ViewHolder {
TextView txtItem;
EditText etValue;
public ViewHolder(View view) {
txtItem = view.findViewById(R.id.tvUnitName);
etValue = view.findViewById(R.id.etValue);
}
}
}
unit_row.xml
<?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:scrollbars="vertical"
android:paddingLeft="5dp"
android:weightSum=".2"
android:orientation="horizontal">
<TextView
android:id="#+id/tvUnitName"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center|left"
android:text="Unit"
android:textSize="16sp"
android:paddingLeft="5dp"
android:layout_weight=".1"
/>
<EditText
android:id="#+id/etValue"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="right"
android:text="100"
android:inputType="numberDecimal"
android:textSize="16sp"
android:paddingRight="15dp"
android:layout_margin="5dp"
android:layout_weight=".1"
/>
</LinearLayout>
activity_main.xml
<?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"
android:orientation="vertical"
tools:context=".MainActivity">
<ListView
android:id="#+id/unitc_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Problems:
addTextChangedListener are being called multiple times unnecessarily
Values are not updating properly.
Thanks in advance for the help.
I'm trying to show an additional CardView that contains a different layout but have got lost with my code. I'm also unsure of how to to show the array of strings within a GridView for the CardView itself. Does anyone know where I may have gone wrong & what can be done so that the following can be achieved?:
Place the CardView containing the GridView wherever I want within the RecyclerView.
Show the array of strings in a GridView within a CardView
What I want to add to the RecyclerView (above the Item A CardView)
RecyclerView current contents
Fragment class
public class MyFragment extends android.support.v4.app.Fragment {
private MonRecyclerAdapterWithGrid adapterG;
static final String[] frenchVowels = new String[]{
"a", "e", "i", "o", "u", "y"
};
public MyFragment() {}
#Override
public View onCreateView(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;
recyclerView = v.findViewById(R.id.my_recyclerview);
linearLayoutManager = new LinearLayoutManager(getActivity());
MyRecyclerAdapter adapter = new MyRecyclerAdapter(getContext(), getHeader(), getListItemsG(), getListItemsT());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
super.onActivityCreated(savedInstanceState);
}
RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
public RecyclerViewHeader getHeader()
{
return new RecyclerViewHeader();
}
public List<RecyclerViewItemGV> getListItemsG() {
List<RecyclerViewItemGV> rvItemsG = new ArrayList<>();
RecyclerViewItemGV itemG = new RecyclerViewItemGV();
itemG.setTitleGV("Item A");
itemG.setVowelsGV(adapterG);
for (String fVowels : frenchVowels) {
// ?????? Still not working :-(
adapterG.addAdapterItem(new MyFragment.AdapterItem(frenchVowels));
}
rvItemsG.add(itemG);
return rvItemsG;
}
public List<RecyclerViewItemTV> getListItemsT()
{
List<RecyclerViewItemTV> rvItemsT = new ArrayList<>();
RecyclerViewItemTV itemA = new RecyclerViewItemTV();
itemA.setTitleTV("Item A");
itemA.setDescriptionTV("Feature A1");
rvItemsT.add(itemA);
RecyclerViewItemTV itemB = new RecyclerViewItemTV();
itemB.setTitleTV("Item B");
itemB.setDescriptionTV("Feature B1\nFeature B2");
rvItemsT.add(itemB);
RecyclerViewItemTV itemC = new RecyclerViewItemTV();
itemC.setTitleTV("Item C");
itemC.setDescriptionTV("Feature C1\nFeature C2\nFeature C3");
rvItemsT.add(itemC);
return rvItemsT;
}
}
RecyclerView adapter class
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEMG = 1;
private static final int TYPE_ITEMT = 2;
private Context mContext;
RecyclerViewHeader header;
List<RecyclerViewItemGV> listItemsG;
List<RecyclerViewItemTV> listItemsT;
ValueAnimator mAnimator;
public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<RecyclerViewItemGV> listItemsG, List<RecyclerViewItemTV> listItemsT)
{
this.mContext = context;
this.header = header;
this.listItemsG = listItemsG;
this.listItemsT = listItemsT;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEADER)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header_expandcollapsebuttons, parent, false);
return new MyRecyclerAdapter.VHHeader(v);
}
else if(viewType == TYPE_ITEMG)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_gv, parent, false);
return new MyRecyclerAdapter.VHItemG(v);
}
else if(viewType == TYPE_ITEMT)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_tv, parent, false);
return new MyRecyclerAdapter.VHItemT(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
private RecyclerViewItemGV getItemG(int position)
{
return listItemsG.get(position);
}
private RecyclerViewItemTV getItemT(int position)
{
return listItemsT.get(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Typeface iconFont = FontManager.getTypeface(mContext, FontManager.FONTAWESOME);
if (holder instanceof MyRecyclerAdapter.VHHeader)
{
final MyRecyclerAdapter.VHHeader vhHeader = (MyRecyclerAdapter.VHHeader)holder;
}
else if (holder instanceof MyRecyclerAdapter.VHItemG){
RecyclerViewItemGV currentItemG = getItemG(position-1);
final MonRecyclerAdapterWithGrid.VHItemG vhItemG = (MyRecyclerAdapter.VHItemG)holder;
vhItemG.txtAG.setText(currentItemG.getTitleGV());
vhItemG.mGridViewG.setVisibility(View.GONE);
vhItemG.txtExpandCollapseG.setText(R.string.fa_icon_chevron_down);
vhItemG.txtExpandCollapseG.setTypeface(iconFont);
//Add onPreDrawListener
vhItemG.mGridViewG.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
vhItemG.mGridViewG.getViewTreeObserver().removeOnPreDrawListener(this);
vhItemG.mGridViewG.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItemG.mGridViewG.measure(widthSpec, heightSpec);
vhItemG.mGridViewHeight = vhItemG.mGridViewG.getMeasuredHeight();
return true;
}
});
vhItemG.mCardViewG.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItemG.mGridViewG.getVisibility() == View.GONE){
vhItemG.expandG();
} else {
vhItemG.collapseG();
}
}
});
}
else if (holder instanceof MyRecyclerAdapter.VHItemT)
{
RecyclerViewItemTV currentItem = getItemT(position-2);
final MyRecyclerAdapter.VHItemT vhItemT = (MyRecyclerAdapter.VHItemT)holder;
vhItemT.txtA.setText(currentItem.getTitleTV());
vhItemT.txtB.setText(currentItem.getDescriptionTV());
vhItemT.txtB.setVisibility(View.GONE);
vhItemT.txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
vhItemT.txtExpandCollapse.setTypeface(iconFont);
//Add onPreDrawListener
vhItemT.txtB.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
vhItemT.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItemT.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItemT.txtB.measure(widthSpec, heightSpec);
vhItemT.textBHeight = vhItemT.txtB.getMeasuredHeight();
return true;
}
});
vhItemT.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(vhItemT.txtB.getVisibility() == View.GONE){
vhItemT.expandT();
} else {
vhItemT.collapseT();
}
}
});
}
}
// need to override this method
#Override
public int getItemViewType(int position) {
if(isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEMG;
return TYPE_ITEMT;
}
private boolean isPositionHeader(int position)
{
return position == 0;
}
#Override
public int getItemCount() {
return listItemsG.size()+1;
return listItemsT.size()+1;
}
class VHHeader extends RecyclerView.ViewHolder{
Button btnCollapseAll, btnExpandAll;
public VHHeader(View headerView) {
super(headerView);
this.btnCollapseAll = headerView.findViewById(R.id.btn_collapseall);
this.btnExpandAll = headerView.findViewById(R.id.btn_expandall);
}
}
public class VHItemG extends RecyclerView.ViewHolder{
CardView mCardViewG;
LinearLayout mLinearLayoutG;
RelativeLayout mRelativeLayoutG;
RecyclerView mRecyclerViewG;
GridView mGridViewG;
TextView txtExpandCollapseG, txtAG;
public int mGridViewHeight;
public VHItemG(View itemView) {
super(itemView);
this.mCardViewG = itemView.findViewById(R.id.cv_gv);
this.mLinearLayoutG = itemView.findViewById(R.id.linearlayout_gv_titlerow);
this.mRelativeLayoutG = itemView.findViewById(R.id.relativelayout_gv);
this.mRecyclerViewG = itemView.findViewById(R.id.my_recyclerview);
this.txtAG = itemView.findViewById(R.id.tv_gv_A);
this.txtExpandCollapseG = itemView.findViewById(R.id.tv_gv_expandcollapse);
this.mGridViewG = itemView.findViewById(R.id.gv_a);
}
private void expandG() {
// change visibility to 'VISIBLE'
mGridViewG.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapseG.setText(R.string.fa_icon_chevron_up);
// apply animation to the height of 'txtB'
mAnimator = slideAnimator(0, mGridViewHeight);
// start the animation
mAnimator.start();
}
private void collapseG() {
// change direction of chevron to 'down'
txtExpandCollapseG.setText(R.string.fa_icon_chevron_down);
int finalHeight = mGridViewG.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animator) {
// Height will be 0, but set visibility to 'GONE'
mGridViewG.setVisibility(View.GONE);
}
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
public ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// update height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = mGridViewG.getLayoutParams();
layoutParams.height = value;
mGridViewG.setLayoutParams(layoutParams);
}
});
return animator;
}
}
public class VHItemT extends RecyclerView.ViewHolder{
CardView cardView;
LinearLayout mLinearLayout;
RecyclerView mRecyclerView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public int textBHeight;
public VHItemT(View itemView) {
super(itemView);
this.cardView = itemView.findViewById(R.id.linearlayout_tv_main);
this.mLinearLayout = itemView.findViewById(R.id.linearlayout_tv_titlerow);
this.mRelativeLayout = itemView.findViewById(R.id.relativelayout_tv);
this.mRecyclerView = itemView.findViewById(R.id.my_recyclerview);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_tv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_tv_A);
this.txtB = itemView.findViewById(R.id.tv_tv_B);
}
private void expandT() {
// change visibility to 'VISIBLE'
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
// apply animation to the height of 'txtB'
mAnimator = slideAnimator(0, textBHeight);
// start the animation
mAnimator.start();
}
private void collapseT() {
// change direction of chevron to 'down'
txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
int finalHeight = txtB.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animator) {
// Height will be 0, but set visibility to 'GONE'
txtB.setVisibility(View.GONE);
}
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
public ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// update height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = txtB.getLayoutParams();
layoutParams.height = value;
txtB.setLayoutParams(layoutParams);
}
});
return animator;
}
}
}
GridView adapter (currently excluded from project)
private class MyGVAdapter extends ArrayAdapter<AdapterItem> {
private List<AdapterItem> items = new ArrayList<>();
MyGVAdapter(Context context, int textviewid) {
super(context, textviewid);
}
void addAdapterItem(MyGVFragment.AdapterItem item) {
items.add(item);
}
#Override
public int getCount() {
return items.size();
}
#Override
public MyGVFragment.AdapterItem getItem(int position) {
return ((null != items) ? items.get(position) : null);
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public View getView(final int position, View convertView, #NonNull final ViewGroup parent) {
View rowView;
if (convertView == null) {
rowView = getActivity().getLayoutInflater().inflate(R.layout.gridview_item, parent, false);
} else {
rowView = convertView;
}
TextView tv = rowView.findViewById(R.id.item_gridview);
tv.setText(items.get(position).first);
return rowView;
}
}
class AdapterItem {
String first;
AdapterItem(String first) {
this.first = first;
}
}
}
gridview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/item_gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="0dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
/>
</LinearLayout>
CardView with GridView (recyclerview_item_gv)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:id="#+id/cv_gv"
android:layout_marginBottom="20dp"
>
<LinearLayout
android:id="#+id/lineralayout_gv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:animateLayoutChanges="true">
<LinearLayout
android:id="#+id/linearlayout_gv_titlerow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="2dp"
android:weightSum="100">
<TextView
android:id="#+id/tv_gv_A"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Medium" />
<TextView
android:id="#+id/tv_gv_expandcollapse"
android:importantForAccessibility="no"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Large" />
</LinearLayout>
<RelativeLayout
android:id="#+id/relativelayout_gv"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridView
android:id="#+id/gv_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:numColumns="auto_fit"
android:layout_marginBottom="20dp"
android:stretchMode="columnWidth" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
CardView with TextView (recyclerview_item_tv.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:id="#+id/cv_tv"
android:layout_marginBottom="20dp">
<LinearLayout
android:id="#+id/linearlayout_gv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:animateLayoutChanges="true">
<LinearLayout
android:id="#+id/linearlayout_tv_titlerow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="2dp"
android:weightSum="100">
<TextView
android:id="#+id/tv_tv_A"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Medium" />
<TextView
android:id="#+id/tv_tv_expandcollapse"
android:importantForAccessibility="no"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Large" />
</LinearLayout>
<RelativeLayout
android:id="#+id/relativelayout_tv"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tv_B"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
style="#android:style/TextAppearance.Large" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Ok so I made a quick example of how to do it. This is how the Activity class I'm posting looks like, all items are in the same RecyclerView:
Bear in mind, it might not look like your code because I am trying to use (At least for me) best practices, and also shorten the amount of code and classes by containing a lot of things in the same class.
Here is the Activity:
public class RecyclerActivity extends AppCompatActivity {
RecyclerView recycler;
ArrayList<String> data;
RecyclerView.Adapter<ViewHolder> adapter;
private static final int ITEM_TYPE = 100;
private static final int HEADER_TYPE = 101;
private static final int HEADER_TYPE_2 = 102;
private static final int GRID_TYPE = 103;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
// find recycler,
recycler = findViewById(R.id.recycler);
// set the layout
recycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
// init data,
data = new ArrayList<>();
data.add("Item A");
data.add("Item B");
data.add("Item C");
// create the adapter
adapter = createAdapter();
// set the adapter
recycler.setAdapter(adapter);
}
// creates the adapter,
private RecyclerView.Adapter<ViewHolder> createAdapter() {
return new RecyclerView.Adapter<ViewHolder>() {
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int type) {
switch (type) {
case HEADER_TYPE:
// inflate the layout,
ViewHolder holderHeader1 = new ViewHolder(inflateHelper(R.layout.header, parent));
// set an on click to the view here to create only one object,
holderHeader1.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
return holderHeader1;
case HEADER_TYPE_2:
// inflate the layout,
ViewHolder holderHeader2 = new ViewHolder(inflateHelper(R.layout.header, parent));
// set an on click to the view here to create only one object,
holderHeader2.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
return holderHeader2;
case ITEM_TYPE:
// inflate the layout,
ViewHolder holderItem = new ViewHolder(inflateHelper(R.layout.item, parent));
// set an on click to the view here to create only one object,
holderItem.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
return holderItem;
case GRID_TYPE:
// inflate the layout,
ViewHolder holderGrid = new ViewHolder(inflateHelper(R.layout.grid, parent));
// set an on click to the view here to create only one object,
holderGrid.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
return holderGrid;
default:
// inflate the layout,
ViewHolder holderItemDefault = new ViewHolder(inflateHelper(R.layout.item, parent));
// set an on click to the view here to create only one object,
holderItemDefault.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
return holderItemDefault;
}
}
/**
* Keep the viewholder simple and the all the view finding here. This way you
* only have one viewholder.
*/
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
// go through the positions
switch (getItemViewType(position)) {
case HEADER_TYPE:
Button expandButton = viewHolder.itemView.findViewById(R.id.button);
expandButton.setText("Expand");
break;
case HEADER_TYPE_2:
Button collapseButton = viewHolder.itemView.findViewById(R.id.button);
collapseButton.setText("Collapse");
break;
case ITEM_TYPE:
// get the current item
String item = data.get(position - 3);
TextView title = viewHolder.itemView.findViewById(R.id.title);
title.setText(item);
break;
case GRID_TYPE:
break;
}
}
#Override
public int getItemCount() {
return data.size() + 3;
}
#Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return HEADER_TYPE;
case 1:
return HEADER_TYPE_2;
case 2:
return GRID_TYPE;
default: return ITEM_TYPE;
}
}
};
}
private View inflateHelper(int resId, ViewGroup parent) {
return LayoutInflater.from(this).inflate(resId, parent, false);
}
// inner class for viewholder to use,
class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(#NonNull View itemView) {
super(itemView);
}
}
}
You might notice that I have used one ViewHolder. This is a pattern I believe we should adopt because it simplifies code so much more. You can find the views you need in the onBind method and thus get away with using one for all types of views.
Also I add the on click listener in the onCreateViewHolder because it is much more efficient to set it there, and it allows for the viewholder to not be onClick specific.
As I said, you can use as many types as you want, you just need to check for it, and set it at the right position.
Here are the layout files if you are interested:
Header
<?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:padding="4dp"
android:gravity="center">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Expand" />
</LinearLayout>
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:padding="16dp"
android:elevation="2dp"
android:layout_margin="16dp"
android:background="#drawable/rounded">
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Item A"
android:textColor="#fff"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_chevron_right"
android:tint="#fff"/>
</LinearLayout>
Grid Layout (I cheated a bit here because I didn't see a reason to not hardcode vowels, although you might need to do it dynamically)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:padding="16dp"
android:background="#drawable/rounded"
android:backgroundTint="#fff"
android:elevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="16dp"
android:text="French Vowels"
android:textStyle="bold"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/a"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="a"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
<TextView
android:id="#+id/e"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="e"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
<TextView
android:id="#+id/i"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="i"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/o"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="o"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
<TextView
android:id="#+id/u"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="u"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
<TextView
android:id="#+id/y"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"
android:text="y"
style="#style/Base.TextAppearance.AppCompat.Medium"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
Rounded Drawable
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#222"/>
<corners android:radius="6dp"/>
</shape>
For anyone reading, if you happen to use Kotlin, consider using my small library which eliminates this recycler view boilerplate to a simple chain of functions:
https://github.com/Pfuster12/BoilerCycle
I'm trying to populate a listView and am getting a nullPointerException. When I debug the program, I see that the TextView's are all null, ie. the findViewById is not working for some reason. Any advice?
The favouritesActivity populates the activity_favourites listView, using favourite_list_layout as the format for each element in the list.
activity to populate lists
public class favouritesActivity extends AppCompatActivity {
String[] titles, authors, publishers, ISBN;
DBConnection dbConnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favourites);
ListView favouritesListView = (ListView) findViewById(R.id.favouritesListView);
//Below populates title and author string lists
//connecting to DB
dbConnection = new DBConnection(this);
//populating list with
List<Book> favouriteBookList = dbConnection.getAllFavBooks();
//below i am populating lists with book data (title and author)
titles = new String[favouriteBookList.size()];
for (int i=0; i<favouriteBookList.size(); i++){
titles[i] = favouriteBookList.get(i).title;
}
authors = new String[favouriteBookList.size()];
for (int i=0; i<favouriteBookList.size(); i++){
authors[i] = favouriteBookList.get(i).authorsString;
}
publishers = new String[favouriteBookList.size()];
for (int i=0; i<favouriteBookList.size(); i++){
publishers[i] = favouriteBookList.get(i).publisher;
}
ISBN = new String[favouriteBookList.size()];
for (int i=0; i<favouriteBookList.size(); i++){
ISBN[i] = favouriteBookList.get(i).isbn;
}
CustomAdapter customAdapter = new CustomAdapter();
favouritesListView.setAdapter(customAdapter);
}
class CustomAdapter extends BaseAdapter{
#Override
public int getCount() {
return titles.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.favourite_list_layout, null);
final int index = i;
TextView titleTV = (TextView) findViewById(R.id.favouriteTitle);
TextView authorTV = (TextView) findViewById(R.id.favouriteAuthor);
TextView publisherTV = (TextView) findViewById(R.id.favouritePublisher);
Button deleteFavButton = (Button) findViewById(R.id.deleteFavButton);
titleTV.setText(titles[index]);
authorTV.setText(authors[index]);
publisherTV.setText(publishers[index]);
deleteFavButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dbConnection.removeFavBook(ISBN[index]);
}
});
return view;
}
}
}
favourite_list_layout - the layout of each element of the list
<?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">
<TextView
android:id="#+id/favouriteTitle"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:text="TextView" />
<TextView
android:id="#+id/favouriteAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/favouriteTitle"
android:layout_alignStart="#+id/favouriteTitle"
android:layout_below="#+id/favouriteTitle"
android:text="TextView" />
<TextView
android:id="#+id/favouritePublisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/favouriteAuthor"
android:layout_alignStart="#+id/favouriteAuthor"
android:layout_below="#+id/favouriteAuthor"
android:text="TextView" />
<Button
android:id="#+id/deleteFavButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/favouriteAuthor"
android:layout_alignBottom="#+id/favouriteAuthor"
android:layout_marginLeft="38dp"
android:layout_marginStart="38dp"
android:layout_toEndOf="#+id/favouriteTitle"
android:layout_toRightOf="#+id/favouriteTitle"
android:text="Delete" />
</RelativeLayout>
You need to be calling findViewById() on the layout you inflated and not on your activity. That is, replace
TextView titleTV = (TextView) findViewById(R.id.favouriteTitle);
with
TextView titleTV = (TextView) view.findViewById(R.id.favouriteTitle);
and similarly for your other views.
I'm working on an Android application for placing orders, and I have an activity with an Expandable ListView, which I populate by parsing a JSON file. Now, in each row of the Expandable ListView I have an EditText Field for entering amount, and on a button click I would like to get all the children that have a value different than 0 in that EditText field, and put the data in a database (for the products and the amount that has been ordered).
I would need a help creating a function for getting those elements, since I've struggled with that recently.
Here is my code
Expandable List Adapter:
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<Artikl>> _listDataChild;
public ExpandableListAdapter(Context context, List<String>
listDataHeader,
HashMap<String, List<Artikl>>
listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
#Override
public Object getChild(int groupPosition, int childPosititon) {
return
this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getChildAmount(int groupPosition, int childPosition,View
convertView) {
int kolicina;
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
}
EditText amount = (EditText)
convertView.findViewById(R.id.editText);
kolicina=Integer.parseInt(amount.getText().toString());
return kolicina;
}
#Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView,
ViewGroup
parent) {
final Artikl child = (Artikl) getChild(groupPosition,
childPosition);
final String childText = child.getNaziv();
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.from_name);
txtListChild.setText(childText);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return
this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
#Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
#Override
public int getGroupCount() {
return this._listDataHeader.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}}
List_item.xml
<?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:orientation="vertical"
android:paddingTop="2.5dp"
android:paddingBottom="2.5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:orientation="horizontal"
android:padding="10dp" >
<TextView
android:id="#+id/from_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/thumbnail"
android:text="Pineapple"
android:textColor="#040404"
android:textSize="15dip"
android:typeface="sans" />
<LinearLayout
android:id="#+id/cart_plus_minus_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/from_name"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/cena_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:paddingRight="25dip"
android:text="100 gm"
android:textColor="#343434"
android:textSize="12dip" />
<TextView
android:text="Amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView" />
<EditText
android:layout_width="48dp"
android:layout_height="66dp"
android:inputType="textPersonName"
android:ems="10"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/from_name"
android:layout_toEndOf="#+id/from_name"
android:layout_marginLeft="21dp"
android:layout_marginStart="21dp"
android:id="#+id/editText"
android:layout_weight="0.08"
android:hint="0"
android:text="0" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
ListGroup.xml
<?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="wrap_content"
android:orientation="vertical"
android:padding="8dp"
android:background="#0a2859">
<TextView
android:id="#+id/lblListHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?
android:attr/expandableListPreferredItemPaddingLeft"
android:textSize="17dp"
android:textColor="#ffffff" />
</LinearLayout>
Order Activity Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#f4f4f4" >
<TextView android:layout_width="fill_parent"
android:layout_height="70dp"
android:id="#+id/market_dolg"
android:background="#8090aa"
android:textColor="#android:color/white"
android:textSize="18dp"
android:text="Hello!"
android:gravity="center"/>
<ExpandableListView
android:id="#+id/lvExp"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="#id/market_dolg"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_below="#id/lvExp"
android:id="#+id/otkazi"
android:background="#9ea6a8"
android:textColor="#android:color/white"
android:textSize="18dp"
android:text="Cancel Order"
android:onClick="Otkazi_nar"
android:gravity="center"
android:layout_alignParentLeft="true"
android:orientation="horizontal"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_below="#id/lvExp"
android:id="#+id/order"
android:background="#3fa5ba"
android:textColor="#android:color/white"
android:textSize="18dp"
android:text="Order"
android:gravity="center"
android:layout_alignParentRight="true"
android:orientation="horizontal"
/>
</RelativeLayout>
Order Activity Java code:
public class Order extends Activity {
private static final String TAG = Order.class.getSimpleName();
private static final String url = "artikli.json";
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
public List<Artikl> voda = new ArrayList<Artikl>();
public List<Artikl> sok = new ArrayList<Artikl>();
HashMap<String, List<Artikl>> listDataChild;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_naracka);
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader,
listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
// Listview Group click listener
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return false;
}
});
}
/*
* Preparing the list data
*/
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<Artikl>>();
// Adding child data
listDataHeader.add("Вода");
listDataHeader.add("Сок");
// Adding child data
JsonArrayRequest Req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
String sifra = obj.getString("sifra");
if (sifra.equals("1")) {
Artikl artikl = new Artikl();
artikl.setNaziv(obj.getString("naziv"));
artikl.setCena(obj.getInt("cena"));
artikl.setSifra(sifra);
artikl.setEdm(obj.getString("edm"));
voda.add(artikl);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(Req);
JsonArrayRequest Req1 = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
String sifra = obj.getString("sifra");
if (sifra.equals("2")) {
Artikl artikl1 = new Artikl();
artikl1.setNaziv(obj.getString("naziv"));
artikl1.setCena(obj.getInt("cena"));
artikl1.setSifra(obj.getString("sifra"));
artikl1.setEdm(obj.getString("edm"));
sok.add(artikl1);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(Req1);
listDataChild.put(listDataHeader.get(0), voda);
listDataChild.put(listDataHeader.get(1), sok);
}}
And the Model (Artikl.java) has only Get and Set methods
In getChildView method of adapter add addTextChangedListener to edittext and in afterTextChanged method save enter text in database, if you want to get only numbers then restrict the keyboard number
mEtReference.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.length() > 0) {
int value = Integer.parseInt(editable + "");
// save value
}
}
});
I am Using a list view inside a listview and both listview share same list item.
It is working fine but if height of the item increases in inside list view it doesn't wrap the content and put a scrollview which is not as per requirement.
Please see the codes below
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<ListView
android:id="#+id/list_comments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:divider="#android:color/transparent"
android:dividerHeight="5dp" />
</RelativeLayout>
comments_for_topic.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:layout_gravity="bottom"
android:background="#fafafa">
<RelativeLayout
android:id="#+id/commentsRelLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingLeft="7dp"
android:background="#d5d5d5"
android:orientation="vertical">
<TextView
android:id="#+id/UserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="User name"/>
<TextView
android:id="#+id/Comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/UserName"
android:textSize="12sp"
android:padding="5dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="#+id/showRep"
android:text="Comment test 1"/>
<TextView
android:id="#+id/showRep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2Replies"
android:layout_toLeftOf="#+id/Reply"
android:layout_marginRight="3dp"
android:textSize="12dp"
android:textColor="#android:color/holo_blue_dark"
android:layout_below="#+id/UserName"/>
<TextView
android:id="#+id/Reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reply"
android:textSize="12dp"
android:textColor="#android:color/holo_blue_dark"
android:layout_below="#+id/UserName"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<ListView
android:id="#+id/list_commentsLevel1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/commentsRelLayout"
android:layout_alignLeft="#+id/commentsRelLayout"
android:layout_marginLeft="34dp"
android:background="#d5d5d5"
android:layout_marginTop="2dp"
android:scrollbars="none"
android:divider="#android:color/white"
android:dividerHeight="1dp"
></ListView>
<TextView
android:id="#+id/showmorebtn"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/show_more"
android:layout_below="#+id/list_commentsLevel1"
android:layout_alignLeft="#+id/list_commentsLevel1"
android:textColor="#android:color/holo_blue_dark"
/>
</RelativeLayout>
AdapterComments.java
public class AdapterComments extends BaseAdapter {
private Activity activity;
private ArrayList<CommentListModel> itemsArrayList = new ArrayList<CommentListModel>();
private ArrayList<CommentListModel> Comments = new ArrayList<CommentListModel>();
CommentListModel tempValues=null;
private static LayoutInflater inflater=null;
ArrayList<AdapterComments> adapterCommentsArrayList = new ArrayList<AdapterComments>();
ViewHolder holder = new ViewHolder();
ViewHolder viewHolder;
ArrayList<String> list =new ArrayList<String>();
private int currentID=0;
boolean isChild =false;
FragmentDiscussinTopic fragmentDiscussinTopic;
public AdapterComments() {
}
public AdapterComments(Activity context, FragmentDiscussinTopic fragmentDiscussinTopic, ArrayList<CommentListModel> itemsArrayList) {
this.activity = context;
this.itemsArrayList = itemsArrayList;
this.isChild = false;
this.fragmentDiscussinTopic = fragmentDiscussinTopic;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0 ; i<itemsArrayList.size();i++){
AdapterComments adapterComments1 = new AdapterComments();
adapterCommentsArrayList.add(adapterComments1);
}
}
public AdapterComments(Activity context, ArrayList<CommentListModel> itemsArrayList) {
this.activity = context;
this.itemsArrayList = itemsArrayList;
this.isChild = true;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0 ; i<itemsArrayList.size();i++){
AdapterComments adapterComments1 = new AdapterComments();
adapterCommentsArrayList.add(adapterComments1);
}
}
#Override
public int getCount() {
if(itemsArrayList.size()<=0)
return 1;
return itemsArrayList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public Object getItem(int position) {
return position;
}
public static class ViewHolder{
public TextView UserName;
public TextView Comment;
public TextView showRep;
public TextView Reply;
public TextView showmorebtn;
public ListView list_commentsLevel1;
}
#Override
public View getView(final int position, View rowView, ViewGroup parent) {
View v1 = rowView;
if(rowView==null){
v1 = inflater.inflate(R.layout.comments_for_topic,null);
viewHolder =new ViewHolder();
viewHolder.UserName=(TextView)v1.findViewById(R.id.UserName);
viewHolder.Comment=(TextView)v1.findViewById(R.id.Comment);
viewHolder.showRep=(TextView)v1.findViewById(R.id.showRep);
viewHolder.showmorebtn=(TextView)v1.findViewById(R.id.showmorebtn);
viewHolder.Reply=(TextView)v1.findViewById(R.id.Reply);
viewHolder.list_commentsLevel1=(ListView)v1.findViewById(R.id.list_commentsLevel1);
v1.setTag( viewHolder );
}
else
viewHolder=(ViewHolder)v1.getTag();
if(itemsArrayList.size()<=0)
{
Log.e("data", " no data found");
}
else {
tempValues = itemsArrayList.get(position);
if (tempValues.isVisible()){
viewHolder.list_commentsLevel1.setAdapter(adapterCommentsArrayList.get(position));
viewHolder.list_commentsLevel1.setVisibility(View.VISIBLE);
ObjectAnimator anim = ObjectAnimator.ofFloat(viewHolder.list_commentsLevel1, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();
setListViewHeightBasedOnChildren(viewHolder.list_commentsLevel1);
// scrollMyListViewToBottom();
}else {
Animation animation = new TranslateAnimation(0,0,0,1000);
animation.setDuration(1000);
viewHolder.list_commentsLevel1.startAnimation(animation);
viewHolder.list_commentsLevel1.setVisibility(View.GONE);
}
viewHolder.UserName.setText(tempValues.getUserName());
viewHolder.Comment.setText(tempValues.getComment());
int subcmntcount = tempValues.getSubCommentCount();
if (subcmntcount>=1){
viewHolder.showRep.setVisibility(View.VISIBLE);
if (subcmntcount==1){
String repText=new String("1Reply");
SpannableString content = new SpannableString(repText);
content.setSpan(new UnderlineSpan(), 0, repText.length(), 0);
viewHolder.showRep.setText(content);
}else {
String repText=new String(subcmntcount+"Replies");
SpannableString content = new SpannableString(repText);
content.setSpan(new UnderlineSpan(), 0, repText.length(), 0);
viewHolder.showRep.setText(content);
}
viewHolder.showmorebtn.setVisibility(View.GONE);
}else {
viewHolder.showRep.setVisibility(View.GONE);
viewHolder.list_commentsLevel1.setVisibility(View.GONE);
viewHolder.showmorebtn.setVisibility(View.GONE);
}
if (tempValues.isChild()){
viewHolder.Reply.setVisibility(View.GONE);
viewHolder.showRep.setVisibility(View.GONE);
}else {
viewHolder.Reply.setVisibility(View.VISIBLE);
String repText=new String("Reply");
SpannableString content = new SpannableString(repText);
content.setSpan(new UnderlineSpan(), 0, repText.length(), 0);
viewHolder.Reply.setText(content);
}
v1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0;i<itemsArrayList.size();i++){
CommentListModel commentListModel = ( CommentListModel ) itemsArrayList.get( i );
if (i==position){
isChild =true;
if (commentListModel.getSubCommentCount()>0){
commentListModel.setVisible(true);
itemsArrayList.remove(i);
itemsArrayList.add(i,commentListModel);
new getDiscussionForumComments(commentListModel.getDiscussionCommentID(),position).execute();
}
}else {
commentListModel.setVisible(false);
itemsArrayList.remove(i);
itemsArrayList.add(i,commentListModel);
}
}
}
});
viewHolder.Reply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Configuration.currentDiscussID = itemsArrayList.get(position).getDiscussionCommentID();
fragmentDiscussinTopic.requestEditPop();
}
});
}
return v1;
}
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
int totalHeight=0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++)
{
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
ViewGroup.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + ((listView.getDividerHeight()) * (listAdapter.getCount()));
listView.setLayoutParams(params);
listView.requestLayout();
}
}
please see the highlighted area of image listview height is not proper to wrap the content
any help would be appericiated
The problem is you can't get the scroll of both listview at a time. if you what you both at the same time. you need to create a custom list view try something like this instead of your list view (inside list).
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
Their are some points you need to fix.
Give a proper height to your ListView so that it can scroll within that boundry, wrap_content is never recommended for ListView. So better to put some height to your ListView.
Listview inside a ListView will not give the user experience good. Try a work around or better to Use RecyclerView. RecyclerView is better in performance in case of nested list.
Hope it will help :)