android customised Listview implementation - android

Basically the android list view activity is transparent well i have managed to make it solid black using custom layout but how do i make it like the third image where the corner colour will be random .
thanks in advance
MainActivity.java
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ArrayAdapter;
public class MainActivity extends Activity {
// Declare
private LinearLayout slidingPanel;
private boolean isExpanded;
private DisplayMetrics metrics;
private RelativeLayout headerPanel;
private int panelWidth;
private int panelWidth1;
private ImageView menuViewButton,menuRightButton;
FrameLayout.LayoutParams menuPanelParameters;
FrameLayout.LayoutParams slidingPanelParameters;
LinearLayout.LayoutParams headerPanelParameters;
LinearLayout.LayoutParams listViewParameters;
//Example
////////
String[] Example = new String[]
{ "Android Introduction","Android Setup/Installation","Android Hello World",
"Android Layouts/Viewgroups","Android Activity & Lifecycle","Intents in Android"};
////////
//Example
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layer_stack);
// Initialize
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
panelWidth = (int) ((metrics.widthPixels) * -0.65);//Right panel width
panelWidth1 = (int) ((metrics.widthPixels) * 0.65);//left panel width
headerPanel = (RelativeLayout) findViewById(R.id.header);
headerPanelParameters = (LinearLayout.LayoutParams) headerPanel
.getLayoutParams();
headerPanelParameters.width = metrics.widthPixels;
headerPanel.setLayoutParams(headerPanelParameters);
slidingPanel = (LinearLayout) findViewById(R.id.slidingPanel);
slidingPanelParameters = (FrameLayout.LayoutParams) slidingPanel
.getLayoutParams();
slidingPanelParameters.width = metrics.widthPixels;
slidingPanel.setLayoutParams(slidingPanelParameters);
///////
ArrayAdapter<String> ExampleArrayAdapter = new CustomAdapter(this, Example);
//changing code//practice
/*new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
Example);*/
ListView ExampleListView = (ListView)findViewById(R.id.listView);
ExampleListView.setAdapter(ExampleArrayAdapter);
///////
// Slide the Panel
menuRightButton = (ImageView) findViewById(R.id.menuViewButton);
menuRightButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!isExpanded) {
isExpanded = true;
// Expand
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.menuPanel,
new LeftMenuFragment());
fragmentTransaction.commit();
new ExpandAnimation(slidingPanel, panelWidth1,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.65f, 0, 0.0f, 0, 0.0f);
} else {
isExpanded = false;
// Collapse
new CollapseAnimation(slidingPanel, panelWidth1,
TranslateAnimation.RELATIVE_TO_SELF, 0.65f,
TranslateAnimation.RELATIVE_TO_SELF, 0.0f, 0, 0.0f,
0, 0.0f);
}
}
});
}
}
custom_layout.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="70dp"
android:orientation="horizontal"
android:layout_marginTop="60dp"
android:background="#drawable/blue_bg">
<ImageView
android:id="#+id/imageView1"
android:layout_width="70dp"
android:layout_height="60dp"
android:src="#drawable/ic_launcher"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp"
android:gravity="left" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="19sp"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="20dp"
android:text="Tweet body text here"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginTop="5dp"
android:ellipsize="end"
android:lines="3"
android:textColor="#ffffff"
android:textSize="14sp" />
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Small Text"
android:layout_marginTop="5dp"
android:textColor="#ffffff"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter {
private LayoutInflater inflater;
public CustomAdapter (Activity activity, String[] items){
super(activity, R.layout.custom_layout, items);
inflater = activity.getWindow().getLayoutInflater();
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
return inflater.inflate(R.layout.custom_layout, parent, false);
}
}
I have managed to make it show random colour with updating the get view function with the following code but everytime i scroll the colour changes, how do i make it stable so that once the colour is assigned it won't change?
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
View rowView = inflater.inflate(R.layout.custom_layout, parent, false);
rowView.setBackgroundColor(color);

You have to use a custom adapter with two views. You can change the color of left view in getView method of adapter.

Finally, i have achieved the following answer to my question But i'm still facing the problem where on every scroll the colors are changing , where i want them to be constant once assigned, if anyone can help it will be great. thank you all. By just modifying xml and custom adapter code i have made it my xml code as
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_marginTop="70dp"
android:layout_height="70dp"
android:background="#drawable/blue_bg">
<LinearLayout
android:layout_marginLeft="20dp"
android:layout_width="345dp"
android:layout_height="70dp"
android:background="#drawable/white_bg">
<ImageView
android:id="#+id/imageView1"
android:layout_width="70dp"
android:layout_height="60dp"
android:src="#drawable/ic_launcher"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp"
android:gravity="left" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_marginTop="10dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="19sp"
android:textColor="#000000"
android:textStyle="bold" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="15dp"
android:text="Tweet body text here"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginTop="5dp"
android:ellipsize="end"
android:lines="3"
android:textColor="#000000"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Modifying the java code with the following code
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(257), rnd.nextInt(258));
View rowView = inflater.inflate(R.layout.custom_layout, parent, false);
rowView.setBackgroundColor(color);

Create your layout file as follows.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_weight="0.3" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_weight="0.7" />
</LinearLayout>
Your activity class onCreate() method should look like something like this.
ListView listView = (ListView) findViewById(R.id.listView1);
String[] Example = new String[] { "Android Introduction",
"Android Setup/Installation", "Android Hello World",
"Android Layouts/Viewgroups", "Android Activity & Lifecycle",
"Intents in Android" };
ArrayList<String> list = (ArrayList<String>) Arrays.asList(Example);
CustomAdapter adapter = new CustomAdapter(this, list);
listView.setAdapter(adapter);
Create a custom adapter class as follows.
public class CustomAdapter extends BaseAdapter {
Context context;
ArrayList<String> listOfContents;
LayoutInflater inflater;
public CustomAdapter(Context context, ArrayList<String> list) {
this.context = context;
listOfContents = list;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listOfContents.size();
}
#Override
public Object getItem(int position) {
return listOfContents.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.list_row, null);
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256),
rnd.nextInt(256));
TextView clorText = (TextView) convertView.findViewById(R.id.textView1);
TextView clorText2 = (TextView) convertView
.findViewById(R.id.textView2);
clorText.setBackgroundColor(color);
clorText2.setBackgroundColor(Color.BLACK);
return convertView;
}
}
This code is completely untested. You should get a rough idea about using Listview and Custom adapter and generating random color.

The colour keeps changing because the list items are recycled, now when android calls the getView() method for the second time for a particular list item on scrolling, you regenerate the colour value and it changes.
Since, you are able to generate random colours, all you need to do is to store the colour once the item is generated, and then reuse that colour.
What you could do is to create an array list which stores the colour value and then inside the getView() method check if the colour for a particular position exists in the arraylist. If yes, then use that colour else generate a random colour and also add it to the arraylist of colours.
E.g. (Untested code but the approach should be similar)
Inside getView() :
int color = 0;
if(colorsList.size > position) {
//This means that the color has already been generated for this position
color = colorsList.get(position);
} else {
//Color hasnt been generated for this position.
color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256),
rnd.nextInt(256));
colorsList.add(color);
}
clorText.setBackgroundColor(color);

Related

how to make an expandable list of cardviews?

I searched a lot to find a direct and clear solution for I think a popular problem but unfortunately I couldn't find it.
We want to have a list of cardviews so each card bind to a specific data and each card has a list inside that shows meta or detail data about its parent.
So we have a nested list inside a cardview.
With a simple search, we know that we should use expanded list view which parents items are cardviews and we must have another layout for its child.
So when you click on cards a list of items appears below of your cards on the root.
But we want to show child list inside of cards?
And there is no access to the something like child list id or any other things to refer to a transition animation and change of layout.
So the clear question is how to add a listview inside a cardview?
i follow my work by using tablelayout and table row. and prefer not to use external libraries for stability and version problems.
this is what i mean.
Image that describe my question
If you don't want to use an external library, you can make your CardView expand like this:
Layout file for an expandable CardView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"
>
<TextView
android:id="#+id/textView_name"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold" />
<!--My dropdown Button -->
<RelativeLayout
android:id="#+id/button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end"
android:layout_alignParentRight="true"
android:gravity="center"
>
<View
android:layout_width="12dp"
android:layout_height="12dp"
android:background="#drawable/triangle"
android:layout_alignParentRight="false"
android:layout_alignParentEnd="false" />
</RelativeLayout>
</RelativeLayout>
<!--The layout below is my ExpandableLayout -->
<LinearLayout
android:id="#+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<android.support.v7.widget.AppCompatImageView
android:id="#+id/imageView_Owner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="#+id/textView_Owner"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView_OwnerUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
My ExpandableRecyclerAdapter Class
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class ExpandableRecyclerAdapter extends RecyclerView.Adapter<ExpandableRecyclerAdapter.ViewHolder> {
private List<Repo> repos;
private SparseBooleanArray expandState = new SparseBooleanArray();
private Context context;
public ExpandableRecyclerAdapter(List<Repo> repos) {
this.repos = repos;
//set initial expanded state to false
for (int i = 0; i < repos.size(); i++) {
expandState.append(i, false);
}
}
#Override
public ExpandableRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
this.context = viewGroup.getContext();
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.expandable_card_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ExpandableRecyclerAdapter.ViewHolder viewHolder, final int i) {
viewHolder.setIsRecyclable(false);
viewHolder.tvName.setText(repos.get(i).getName());
viewHolder.tvOwnerLogin.setText("Owner: " +repos.get(i).getOwner().getLogin());
viewHolder.tvOwnerUrl.setText(repos.get(i).getOwner().getUrl());
Picasso.with(context)
.load(repos.get(i).getOwner().getImageUrl())
.resize(500, 500)
.centerCrop()
.into(viewHolder.ivOwner);
//check if view is expanded
final boolean isExpanded = expandState.get(i);
viewHolder.expandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
viewHolder.buttonLayout.setRotation(expandState.get(i) ? 180f : 0f);
viewHolder.buttonLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
onClickButton(viewHolder.expandableLayout, viewHolder.buttonLayout, i);
}
});
}
#Override
public int getItemCount() {
return repos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView tvName,tvOwnerLogin, tvOwnerUrl;
private ImageView ivOwner;
public RelativeLayout buttonLayout;
public LinearLayout expandableLayout;
public ViewHolder(View view) {
super(view);
tvName = (TextView)view.findViewById(R.id.textView_name);
tvId = (TextView)view.findViewById(R.id.textView_id);
tvUrl = (TextView)view.findViewById(R.id.textView_url);
tvOwnerLogin = (TextView)view.findViewById(R.id.textView_Owner);
tvOwnerUrl = (TextView)view.findViewById(R.id.textView_OwnerUrl);
ivOwner = (ImageView) view.findViewById(R.id.imageView_Owner);
buttonLayout = (RelativeLayout) view.findViewById(R.id.button);
expandableLayout = (LinearLayout) view.findViewById(R.id.expandableLayout);
}
}
private void onClickButton(final LinearLayout expandableLayout, final RelativeLayout buttonLayout, final int i) {
//Simply set View to Gone if not expanded
//Not necessary but I put simple rotation on button layout
if (expandableLayout.getVisibility() == View.VISIBLE){
createRotateAnimator(buttonLayout, 180f, 0f).start();
expandableLayout.setVisibility(View.GONE);
expandState.put(i, false);
}else{
createRotateAnimator(buttonLayout, 0f, 180f).start();
expandableLayout.setVisibility(View.VISIBLE);
expandState.put(i, true);
}
}
//Code to rotate button
private ObjectAnimator createRotateAnimator(final View target, final float from, final float to) {
ObjectAnimator animator = ObjectAnimator.ofFloat(target, "rotation", from, to);
animator.setDuration(300);
animator.setInterpolator(new LinearInterpolator());
return animator;
}
}
In your Activity/Fragment, set up RecyclerView like this
private RecyclerView recyclerView;
private List<Repo> data;
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
//fetch data and on ExpandableRecyclerAdapter
recyclerView.setAdapter(new ExpandableRecyclerAdapter(data));
So, its quite simple to create an expandable CardView without external Library. The code is almost exactly the same as using a normal CardView with RecyclerView, the main change is setting the View.GONE/View.VISIBLE on button click.
You can use ExpandLayout,and then add it in cardview.
<com.kyo.expandablelayout.ExpandableLayout
android:id="#+id/expandlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp" >
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#null"
android:scaleType="centerCrop"
android:src="#drawable/parent" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:contentDescription="#null"
android:scaleType="centerCrop"
android:src="#drawable/child"
app:canExpand="true" />
</com.kyo.expandable.ExpandableLayout>

How to set margins to autocompletetextview adapter

I have and autocompletetextview set inside a toolbar. when user provides search query i have an adapter(with some dummy data added for testing) that shows the results based on search query.
The problem is with adapter width as it is set to autocompletetextview width.
But here i want the adapter width to set to toolbar width and a margin between toolbar and adapter.
This is the code i have written:
searchView = (AutoCompleteTextView) findViewById(R.id.searchView);
SearchAdapter searchAdapter = new SearchAdapter(NavigationDrawerActivity.this,searchResults,searchView);
searchView.setAdapter(searchAdapter);
Here is my adapter:
public class SearchAdapter extends ArrayAdapter<SearchResult> {
private boolean mAnimate;
private AutoCompleteTextView mSearch;
public SearchAdapter(Context context, List<SearchResult> options, AutoCompleteTextView search) {
super(context, 0, options);
mSearch = search;
}
int count = 0;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
SearchResult option = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.search_option, parent, false);
/* if (true) {
Animation anim = AnimationUtils.loadAnimation(getContext(),
R.anim.anim_down);
anim.setDuration(400);
convertView.startAnimation(anim);
if (count == this.getCount()) {
mAnimate = false;
}
count++;
}*/
}
View border = convertView.findViewById(R.id.border);
if (position == 0) {
border.setVisibility(View.VISIBLE);
} else {
border.setVisibility(View.GONE);
}
final TextView title = (TextView) convertView
.findViewById(R.id.title);
title.setText(option.title);
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
icon.setImageDrawable(option.icon);
ImageView up = (ImageView) convertView.findViewById(R.id.up);
up.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mSearch.setText(title.getText().toString());
mSearch.setSelection(mSearch.getText().length());
}
});
return convertView;
}
}
Here is my adapter row layout:
<?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="48dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#android:color/white"
android:orientation="horizontal" >
<ImageView
android:id="#+id/icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:paddingLeft="3dp"
android:adjustViewBounds="true"
android:cropToPadding="true" />
<TextView
android:id="#+id/title"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#212121"
android:layout_centerVertical="true"
android:layout_marginLeft="62dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/up"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/up"
android:layout_alignParentRight="true"
android:layout_width="32dp"
android:layout_margin="10dp"
android:layout_marginRight="24dp"
android:layout_gravity="center|right"
android:layout_height="32dp"
android:src="#drawable/ic_up" />
<View
android:id="#+id/border"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#E8E8E8" />
</RelativeLayout>
With the above code i am getting like this:
Need the adapter aligned to toolbar width
I have tried setting adapter width like this:
Rect screenSize = new Rect();
getWindowManager().getDefaultDisplay().getRectSize(screenSize);
// screen width
int screenWidth = screenSize.width();
int adapterMargin = (int)getResources().getDimension(R.dimen.adapter_margin);
searchView.setDropDownWidth(screenWidth - adapterMargin);
But the problem here is i'm getting not getting right margin as shown below:
screen with adapter width set
Please help me on how to tackle this problem.
It looks like you want to set adapter width to be set to toolbar width add the following line to your code it will work:
searchView.setDropDownAnchor(toolbar.getId());
Comment below if you have any further doubts
Modify this line
searchView.setDropDownWidth(screenWidth - adapterMargin);
to the following, may be this will change.
searchView.setDropDownWidth(screenWidth - adapterMargin * 2);

Custom View not giving margin

I am working on an activity where I created a custom view that I am adding dynamically within a LinearLayout. The problem is that I am unable to give margin between the custom views I add.
Here is a look at the two views I added which are next to each other.
Screentshot:
Code for creating the views dynamically:
private void AddSelectedTagUI(final com.main.feedify.serializers.Tags tag){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.tags,tags_section_selectedtags,false);
TextView tagName = (TextView)v.findViewById(R.id.customview_tags_name);
tagName.setText(tag.getTagName());
ImageView close_button = (ImageView)v.findViewById(R.id.customview_tags_close);
close_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RemoveTag(tag.getTagID(), selectedTags);
}
});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
tags_section_selectedtags.addView(v, params);
// cast view to tags and add it in our layout.
// this will help us find out the tag we wanna delete.
view_selectedTags.add(v);
this.UpdateMessage(true);
}
tags.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:padding="5dp"
android:id="#+id/custom_tag"
>
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp"
/>
</RelativeLayout>
activity_tags.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background">
<TextView
android:id="#+id/tags_lbl_taginfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Add at least 4 favorite topics"
android:layout_marginTop="20dp"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_below="#+id/tags_lbl_taginfo"
android:layout_width="match_parent"
android:layout_height="190dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:id="#+id/tags_section_selectedtags">
</LinearLayout>
<EditText
android:id="#+id/tags_txt_tags"
android:layout_below="#+id/tags_section_selectedtags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:hint="Add tags ..."
android:textColor="#color/tags_edittext"
android:paddingTop="15dp"
android:singleLine="true"
android:paddingLeft="9dp"
android:paddingBottom="15dp"
android:background="#drawable/tags_edittext"
/>
<TextView
android:id="#+id/tags_lbl_tagsuggestion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Suggestions"
android:layout_marginTop="15dp"
android:layout_below="#id/tags_txt_tags"
/>
</RelativeLayout>
Custom Tags Class:
package com.main.feedify.custom_views;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.main.feedify.feedify_mockup.R;
import com.tokenautocomplete.TokenCompleteTextView;
/**
* Created by Muazzam on 10/17/2015.
*/
public class Tags extends RelativeLayout{
private com.main.feedify.serializers.Tags tag;
public Tags(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.tags,this);
}
public void setTag(com.main.feedify.serializers.Tags t){
this.tag = t;
}
public com.main.feedify.serializers.Tags getTag(){
return this.tag;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
}
You are setting margins in Pixels. Try converting them into dp, so that the margins value becomes independent of display density.
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = pxToDp(5);
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
private int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
EDIT:
Get rid of the margin code in onLayout() and set those margins, when you are puting this view inside a viewgroup like LinearLayout or RelativeLayout etc.
You should try setting the layout_margin to your RelativeLayoutin your XML file, same as you did with the padding.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:layout_margin="5dp"
android:padding="5dp"
android:id="#+id/custom_tag">
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp" />
</RelativeLayout>
You should add left margin to view while adding it.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//add this line
params.leftMargin=50;
//end
tags_section_selectedtags.addView(v, params);
I think that the problem lays in this piece of code:
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
Here you change the layout parameters inside the onLayout() method and it should lead to the infinite layout of your view: custom view's parent view calls onLayout() which calls setLayoutParams() which results in onLayout()... And so it goes.
One way to prevent this behavior is to add your margins in tags.xml file, just like you did with the paddings. The infinite layout loop will be gone and your view will have a chance to set its margins.
I have designed a view dynamically and have given parameters such like yours, have a look at this code:
https://stackoverflow.com/a/33339420/5479863
and to convert into dp from pixel use this method
private int getPixelsToDP(int dp) {
float scale = getResources().getDisplayMetrics().density;
int pixels = (int) (dp * scale + 0.5f);
return pixels;
}

android onListItemClick not working when spinners populated within listrow

I am trying to populate a listview in which the rows contain a checkbox, four textviews, and two spinners. The values in the spinners on each row need to be different as they directly relate to the actual item on that row. Just to make it that little bit more complicated the spinners and the two text fields beside them are not visible (setVisibility(View.GONE)) unless the checkbox is checked. I just want the list item click-able (not the checkbox), and the spinners need to be click-able once they are shown.
All of my code is working correctly except that when the spinners are populated then I lose the ability to click the list item on that row. I can still choose values from the spinners on that row but touching anywhere else on the row does nothing at all. There are some rows that don't return data to the spinners and they continue to operate correctly so I believe it is something to do with the adaptors connected to the spinners.
Also I know I will have to account for the list view recycling but I haven't got that far yet.
I hope someone can point out what is wrong here before I go completely insane.
Here is the listview xml
<ListView android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<TextView android:id="#+id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/empty"/>
</LinearLayout>
And here is the row xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<CheckBox android:id="#+id/pl_selected"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:layout_weight="1"/>
<TextView android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"/>
<TextView android:id="#+id/name2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/pl_tv1"
android:text="#string/pl_tv1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:visibility="gone"/>
<Spinner android:id="#+id/pl_spin1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="gone"
android:focusableInTouchMode="false"
android:focusable="false"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/pl_tv2"
android:text="#string/pl_tv2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:visibility="gone"/>
<Spinner android:id="#+id/pl_spin2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="gone"
android:focusableInTouchMode="false"
android:focusable="false"/>
</LinearLayout>
</LinearLayout>
And here is the activity with most of the irrelevant stuff taken out:
import android.widget.SimpleCursorAdapter;
import mdhsoft.band.Tab.DbAdapter;
import mdhsoft.band.Tab.R;
import android.os.Bundle;
import android.app.ListActivity;
import android.database.Cursor;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
public class PLActivity extends ListActivity {
private static final int DONE_ID = Menu.FIRST;
private DbAdapter mDbHelper;
private int mPlId;
private CheckBox mCheckBox;
private Spinner mSpin1;
private Spinner mSpin2;
private TextView mtv1;
private TextView mtv2;
private int mItemId;
private SimpleCursorAdapter mAllItems;
private Cursor mSCursor;
private Cursor mcurSpin1;
private Cursor mcurSpin2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pl_list);
Bundle extras = getIntent().getExtras();
mPlId = extras.getInt(DbAdapter.KEY_PLID);
mDbHelper = new DbAdapter(this);
mDbHelper.open();
fillData();
registerForContextMenu(getListView());
}
private void fillData() {
mSCursor = mDbHelper.fetchAllPl(mPlId);
startManagingCursor(mSCursor);
String[] from = new String[]
{"pl_selected", DbAdapter.KEY_SNAME, DbAdapter.KEY_SNAME2};
int[] to = new int[]{R.id.pl_selected, R.id.name, R.id.name2};
mAllItems = new SimpleCursorAdapter(this, R.layout.pl_row, mSCursor, from, to);
mAllItems.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 3) {
CheckBox cb = (CheckBox) view;
cb.setChecked(cursor.getInt(3) > 0);
ViewGroup row = (ViewGroup)view.getParent();
if (cursor.getInt(3) > 0) {
mcurSpin1 = (Spinner) row.findViewById(R.id.pl_spin1);
mcurSpin2 = (Spinner) row.findViewById(R.id.pl_spin2);
mtv1 = (TextView) row.findViewById(R.id.pl_tv1);
mtv2 = (TextView) row.findViewById(R.id.pl_tv2);
mcurSpin1.setVisibility(View.VISIBLE);
mtv1.setVisibility(View.VISIBLE);
mcurSpin2.setVisibility(View.VISIBLE);
mtv2.setVisibility(View.VISIBLE);
PopulateSpinner1();
PopulateSpinner2();
}
return true;
}
return false;
}
});
setListAdapter(mAllItems);
}
private void PopulateSpinner1(){
mcurSpin1 = mDbHelper.fetchSByItemId(mItemId);
startManagingCursor(mcurSpin1);
String[] from = new String[]{DbAdapter.KEY_SNAME};
int[] to = new int[]{android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, mcurSpin1, from, to );
adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item);
mSpin1.setAdapter(adapter);
}
private void PopulateSpinner2(){
mcurSpin2 = mDbHelper.fetchMByItemId(mItemId);
startManagingCursor(mcurSpin2);
String[] from = new String[]{DbAdapter.KEY_MNAME};
int[] to = new int[]{android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, mcurSpin2, from, to );
adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item);
mSpin2.setAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ViewGroup row = (ViewGroup)v;
mSCursor.moveToPosition(position);
mItemId = mSCursor.getInt(mSCursor.getColumnIndex(DbAdapter.KEY_SID));
mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected);
mcurSpin1 = (Spinner) row.findViewById(R.id.pl_spin1);
mcurSpin2 = (Spinner) row.findViewById(R.id.pl_spin1);
mtv1 = (TextView) row.findViewById(R.id.pl_tv1);
mtv2 = (TextView) row.findViewById(R.id.pl_tv2);
if (mCheckBox.isChecked()) {
mCheckBox.setChecked(false);
mcurSpin1.setVisibility(View.GONE);
mtv1.setVisibility(View.GONE);
mcurSpin2.setVisibility(View.GONE);
mtv2.setVisibility(View.GONE);
}
else {
mCheckBox.setChecked(true);
mcurSpin1.setVisibility(View.VISIBLE);
mtv1.setVisibility(View.VISIBLE);
mcurSpin2.setVisibility(View.VISIBLE);
PopulateSpinner1();
PopulateSpinner2();
}
}
}
Thanks in advance for any help you can give.
You can try adding android:descendantFocussability=blocksDescendants to the top most linear layout. This might be helpful.

ListView without ListActivity

I'm trying to set a Listview under some other Widgets (Buttons, editText, etc). I don't want to use another activity for the listview. After reading some I found How can I implement a ListView without ListActivity? (use only Activity) and I tried to do it, ending up with:
Here is my main.xml:
<LinearLayout android:id="#+id/relativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="vertical">
<TextView ...[some code].../>
<EditText ...[some code].../>
<ImageButton ...[some code].../>
<Chronometer ..[some code]..../>
<ListView android:id="#+id/listView1" android:layout_height="wrap_content"
android:layout_width="fill_parent"></ListView>
here is my onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (ImageButton) findViewById(R.id.button1);
mChronometer = (Chronometer) findViewById(R.id.chronometer1);
editText1 = (EditText) findViewById(R.id.editText1);
ListView lv = (ListView) findViewById(R.id.listView1);
String[] listword = new String[] {"Hello","World","Foo","Bar"};
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, listword));
}
and here is list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
When I debug in my physical device, the application simply stays all black. If I comment out the lines of onCreate() that involve the list, the application works (obviously without the listview).
Any ideas what might be wrong?
I actually have an app with a listview below some TextViews and above two buttons, let me grab my code!
Here's my activity with listview below the textviews and above the buttons (with quite a bit removed for brevity):
public class BNYDirectoryResults extends Activity{
public static String[] stuff;
ListView list;
BNYAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.resultscreen);
TextView headDisplay = (TextView)findViewById(R.id.results);
TextView headCount = (TextView)findViewById(R.id.resultsTotal);
TextView headPages = (TextView)findViewById(R.id.pages);
//Set up the results list, see BNYAdapter
list = (ListView)findViewById(R.id.list);
adapter = new BNYAdapter (this, BNYDirectory.ReturnResults);
list.setAdapter(adapter);
//Sets up header information (pages, total results)
//Just some stuff to change the TextViews
//Passes EmployeeID and Phone Number to AND opens the details page
list.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String EID = BNYDirectory.ReturnResults[position][0];
String phoneNumber = BNYDirectory.ReturnResults[position][2];
BNYDirectoryTransaction.doDetails(EID, phoneNumber);
Intent i = new Intent(view.getContext(), BNYDirectoryDetails.class);
startActivity(i);
}
});
}
}
Here's the XML file for it:
<TextView
android:id="#+id/results"
android:text="Name"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" android:textStyle="bold"/>
<TextView
android:id="#+id/resultsTotal"
android:text="Phone"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" android:textStyle="bold"/>
<TextView
android:id="#+id/pages"
android:text="AIM"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" android:textStyle="bold"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/name"
android:text="Name"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="#+id/phone"
android:text="Phone"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="#+id/aim"
android:text="AIM"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="#+id/dept"
android:text="Dept"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/prevButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Previous"
android:layout_weight="1"/>
<Button
android:id="#+id/nextButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Next"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
and here's the custom adapter for the list:
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class BNYAdapter extends BaseAdapter {
private Activity activity;
private String[][] results;
private static LayoutInflater inflater=null;
public BNYAdapter(Activity a, String[][]info) {
activity = a;
results = info;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return results.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder{
public TextView name;
public TextView phone;
public TextView aim;
public TextView dept;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.item, null);
holder=new ViewHolder();
holder.name=(TextView)vi.findViewById(R.id.nameItem);
holder.phone=(TextView)vi.findViewById(R.id.phoneItem);
holder.aim=(TextView)vi.findViewById(R.id.aimItem);
holder.dept=(TextView)vi.findViewById(R.id.deptItem);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
holder.name.setText(BNYDirectory.ReturnResults[position][1]);
holder.phone.setText(BNYDirectory.ReturnResults[position][2]);
holder.aim.setText(BNYDirectory.ReturnResults[position][3]);
holder.dept.setText(BNYDirectory.ReturnResults[position][4]);
return vi;
}
}
and all together that makes a page like
You can use your own layout with a ListActivity. Make your activity extend ListActivity, create your own layout and make sure that the ListView has android:id="#android:id/list" (this is how the ListActivity links to the ListView in your own layout), then in onCreate set your layout with setContentView.

Categories

Resources