I have a problem with this separator:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<padding android:left="10dip" android:right="10dip"/>
<solid android:color="#color/listSeparator"/>
<size android:height="1px" />
</shape>
I'm trying to make a little margin/padding in the left/right of the listview component (using a relative on it , not a ListView Object) . Then when i try to put it this way...
getListView().setDivider(getResources().getDrawable(R.drawable.song_separator));
... it's directly ignored , putting a full layout separator .
Now i don't know what is the problem , but i know that :
I can't put a margin in all ListView , cause i want the listHeader fill_parent
I have tried to put a false border , but it isn't nice looking when i change it's background color , putting me a separator space.
Any idea?
MODIFIED
My last partial solution is to put an ImageView , aligned next to the parent bottom .
This is partial cause it puts on the bottom but not on the original divider.
If someone can tell me how to put that ImageView on the exact line of the divider, i would give him the +50 too.
Quiroga so my first bet would be to make the code more debugable by spliting the method call up into individual lines.
ListView lview = getListView();
if (lview != null){
Resources res = getResources();
if (res != null) {
Drawable dable = res.getDrawable(R.drawable.song_separator);
if (dable != null){
lview.setDivider(dable)
}
}
} else {
//Log in some way that you have a problem.
}
I know it looks kind of over complicated but that way you can make sure that the Drawable is found and is the correct one and then properly assigned to the ListView.
Another thing you can try is just assigning a different maybe platform specific separator and see if that works properly.
Also try to get your hands on the Android Source Code it is back online if you add that to your Java Project you can debug into the Platform classes and debug deep into the platform code.
So this isn't really a solution for your problem but maybe it can help you find the solution.
Put the header in a separate file and access it as:
public class AuditActivity extends ListActivity {
Budget budget;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audit);
ListView lv = getListView();
LayoutInflater infalter = getLayoutInflater();
ViewGroup header = (ViewGroup) infalter.inflate(R.layout.header, lv, false);
lv.addHeaderView(header);
budget = new Budget(this);
/*
try {
test = budget.getTransactions();
showEvents(test);
} finally {
}
*/
// switchTabSpecial();
}
Follow this link .......it has a detailed info,use RelativeLayout instead of Linear One, I hope this will help you.
Android: Adding static header to the top of a ListActivity
Related
I want to run the code below in order to tint a button's drawable on pre-lollipop devices, however button.getCompoundDrawables() is returning null for all 4 elements of the array when called inside of the Fragment's onCreateView method.
If I inspect the same Drawable[] array at a later point in time - say upon a button click event - I can see the drawable value has been correctly assigned (3 are null, 1 is valid).
Is there some button life cycle or fragment life cycle that I can rely on the compound drawables array to have been already properly initialized?
Drawable[] drawables = button.getCompoundDrawables();
if( drawables[2] != null){
Drawable wrapDrawable = DrawableCompat.wrap(drawables[2]);
DrawableCompat.setTint(wrapDrawable, color);
button.invalidate();
}
Here's the lib versions I'm using:
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:support-v4:24.1.1'
compile 'com.android.support:design:24.2.0'
At request, I'm including also some xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
[...] >
<Button
android:id="#+id/bt1"
android:background="#android:color/transparent"
android:textAppearance="#style/ConfigButtonTheme"
android:text="Sincronizar Música"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:drawableEnd="#drawable/ic_chevron_right_white_24dp"
android:textAlignment="textStart"
android:layout_width="match_parent"
android:layout_height="60dp" />
</LinearLayout>
for android:drawableRight, you should use getCompoundDrawables(), where as for android:drawableEnd, you should use getCompoundDrawablesRelative().
getCompoundDrawablesRelative()
Change android:drawableEnd to android:drawableRight. Not sure why but drawableEnd returns null in onCreate() method and drawableRight works fine.
You could configure the drawable programmatically and then set it into the text view like so.
val textDrawable = resources.getDrawable(R.drawable.ic_arrow_upward_24dp, null)
val color = ResourcesCompat.getColor(resources, R.color.colorAccent, null)
textDrawable.setTint(color)
//setCompoundDrawablesRelativeWithIntrinsicBounds(left, top, right, bottom)
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, textDrawable, null, null)
Change android:drawableEnd to android:drawableRight. Not sure why but drawableEnd returns null in onCreate() method and drawableRight works fine.
OR
Another way to do without changing android:drawableEnd to android:drawableRight.
It will work 100%
just write your code as follow:
onCreate(){
//your all statement
//at the end
findViewById(android.R.id.content).post(new Runnable() {
#Override
public void run() {
//write your code here you will get all the drawables
}
});
}
In Kotlin returns a list of drawables:
val drawables = (compoundDrawables zip compoundDrawablesRelative).map {
it.first ?: it.second
}
My guess is that the drawable hasn't been created/inflated yet. Try putting that code in either onActivityCreated, onStart or onResume within the Fragment. These are in order of when they will be called within the lifecycle, ideally you want to do this as soon as possible.
It doesn't load your drawables within TextView at the beginning. You should use
TextView.post({
// get your drawables here.
})
this function to get your drawables when it's loaded.
I am making a really simple app (basically a listview with only a few images). It generally performs really well on my testing device (a Motorola Moto G with the stock android that comes with it).
However, I want my ListView to have dotted dividers. Therefore I made a list_divider.xml file defining the divider and set this to be the divider to be used in the ListView. I have tried that out on my Moto G, but it didn't display the line dotted.
So I've googled around and found here a solution to the problem. Disabling hw acceleration for the view solved the error and displayed the divider correctly.
However, now I have another problem: Since disabling hw acceleration the app began to lag when scrolling.
Is there a solution to having a dotted divider and not disabling hw acceleration or at least have the performance nearly as good as before disabling it?
Edit: Here is the adapter code I use:
public class AstronautArrayAdapter extends ArrayAdapter<Astronaut> {
public static final String TAG = "AstronautArrayAdapter";
public AstronautArrayAdapter(Context context, List<Astronaut> objects) {
super(context, R.layout.astronauts_list_row, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RowViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
convertView = inflater.inflate(R.layout.astronauts_list_row, parent, false);
holder = new RowViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.nameOfAustronaut);
holder.daysInSpace = (TextView) convertView.findViewById(R.id.numberOfDaysInSpace);
holder.country = (ImageView) convertView.findViewById(R.id.countryImage);
holder.title = (TextView) convertView.findViewById(R.id.titleOfAstronaut);
convertView.setTag(holder);
} else {
holder = (RowViewHolder) convertView.getTag();
}
Astronaut astronaut = getItem(position);
holder.name.setText(astronaut.getName());
holder.daysInSpace.setText(Integer.toString(astronaut.getDaysInSpace()));
holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));
holder.title.setText(astronaut.getTitle());
return convertView;
}
private static class RowViewHolder {
TextView name;
TextView daysInSpace;
ImageView country;
TextView title;
}
}
Edit 2: Here are the two layout files in question:
activity_main.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/astronautsList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="16dp"
android:dividerHeight="3dp"
android:divider="#drawable/list_divider"
android:layerType="software" />
list_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line" >
<stroke
android:width="1px"
android:color="#android:color/black"
android:dashWidth="5px"
android:dashGap="1px" />
<size android:height="3dp" />
</shape>
possible answer for the lag you're seeing is:
add this line inside the dependencies section to your build.gradle
compile 'com.squareup.picasso:picasso:2.3.2'
and replace this line
holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));
with
Picasso.with(context).load(/* insert the URL here */).into(holder.country);
and remove the code that is downloading all the images and saving locally. Picasso automagically download/decode the bitmaps and manage disk and ram cache for you.
ps.:
if you're not using Gradle:
You should change to Android-Studio and use Gradle
forget what I said about adding the line to the gradle file and just download the jar file from their website, put into the libs folder and make sure to mess on the project settings to make sure that jar goes inside your APK (I honestly do not remember how those settings work because I abandoned Eclipse long time ago)
As you did not mentioned it, have you implemented the ViewHolder pattern?
As the ListView recycles views it has to inflate a layout and insert any text and images in. You normally call findViewById in this section of code which is quite expensive. The ViewHolder pattern solves this and is easy to implement.
See here for a great tutorial by Google
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
What I'm currently doing
Currently, I have changed the scrollbar in my XML file using the android:scrollbarThumbVertical property like so:
<ScrollView
android:id="#+id/scrollView1"
android:scrollbarThumbVertical="#drawable/scrollbar_blue"
... >
And scrollbar_blue refers to my scrollbar_blue.xml file, which is this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="45"
android:centerColor="#color/blue"
android:endColor="#color/blue"
android:startColor="#color/blue" />
<corners android:radius="8dp" />
</shape>
What I want to do
I have a colour option for my app - so when the colour is on, it should stay blue; otherwise, it should be grey.
How can I programmatically (in my activity class) change my ScrollView to use my scrollbar_grey.xml?
If you look at the Android documentation on ScrollView, there is no corresponding method to android:scrollbarThumbVertical
I'm fine with another way change the colour as well.
Here is how I create the reference to my ScrollView:
ScrollView scr = (ScrollView)findViewById(R.id.scrollView1);
There is a method to change it programmatically but that method is not exposed. There doesn't seem to be anything else to change it programmatically from what I have read.
However, I did come across this one stackoverflow answer that uses reflection to do it.
Please upvote the answer there if it works for you: https://stackoverflow.com/a/19819843/3286163
The answer was for a listview but is the same for the scrollview:
ScrollView scr = (ScrollView)findViewById(R.id.scrollView1);
try
{
Field mScrollCacheField = View.class.getDeclaredField("mScrollCache");
mScrollCacheField.setAccessible(true);
Object mScrollCache = mScrollCacheField.get(scr); // scr is your Scroll View
Field scrollBarField = mScrollCache.getClass().getDeclaredField("scrollBar");
scrollBarField.setAccessible(true);
Object scrollBar = scrollBarField.get(mScrollCache);
Method method = scrollBar.getClass().getDeclaredMethod("setVerticalThumbDrawable", Drawable.class);
method.setAccessible(true);
// Set your drawable here.
method.invoke(scrollBar, getResources().getDrawable(R.drawable.scrollbar_blue));
}
catch(Exception e)
{
e.printStackTrace();
}
Only thing I could find. I gave it a try myself and it worked.
In API 29+ use ScrollView.setVerticalScrollbarThumbDrawable() otherwise use the accepted answer.
It is easy nowadays :)
scrollView.verticalScrollbarThumbDrawable = ColorDrawable(Color.CYAN)
scrollView.horizontalScrollbarThumbDrawable = ColorDrawable(Color.WHITE)
This method requires API 29 and higher :
public static void changeBarColor(ScrollView sv, int thumbColor,int trackColor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
sv.getVerticalScrollbarThumbDrawable().setTint(thumbColor);
sv.getVerticalScrollbarTrackDrawable().setTint(trackColor);
}
}
I am currently trying to draw a graph within an Android application. The library I found is called GraphView (http://www.jjoe64.com/p/graphview-library.html). I am currently using version 2, which is available on GitHub.
Drawing graphs works really nicely. The code necessary to get a graph is the following:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Map<String,List<GraphEntry>> graphData = (...)
if (graphData != null) {
List<GraphEntry> entries = graphData.get("temperature");
GraphView.GraphViewData[] data = new GraphView.GraphViewData[entries.size()];
int i = 0;
for (GraphEntry entry : entries) {
data[i++] = new GraphView.GraphViewData(entry.getDate().getTime(), entry.getValue());
}
GraphView.GraphViewSeries graphViewSeries = new GraphView.GraphViewSeries("temperature", 0xffff0000, data);
LineGraphView graphView = new LineGraphView(this, "temperature");
graphView.addSeries(graphViewSeries);
graphView.setShowLegend(true);
LinearLayout graphLayout = (LinearLayout) findViewById(R.id.layout);
graphLayout.addView(graphView);
}
}
This will produce a normal graph. Unfortunately, all kinds of labels are missing. The documentation tells that for the normal use case, one does not have to care about labels, as the library does this automatically. What am I doing wrong? I only get the plain graph, without any labels.
For the completeness, I am adding the graph to a linear layout. The appropriate layout file has the following contents:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:padding="5dp"
android:id="#+id/layout"
android:orientation="vertical"
></LinearLayout>
The GraphEntry class is only a container with a java.util.Date attribute and a double value attribute.
Thank you very much for any help,
Matthias
I switched to another charting engine: AChartEngine. This one works out of the box.
I had the same problem. This can be solved by removing the following line from the manifest file.
android:theme="#style/AppTheme"
I know this is quite vague, but worked for me. I don't the exact reason why this happens. If u guys come across the better solution please do share it.
You should use the latest version from github and include that in your project. This will allow you to set various colours using
graphView.getGraphViewStyle().setGridColor(Color.GREEN);
graphView.getGraphViewStyle().setHorizontalLabelsColor(Color.YELLOW);
graphView.getGraphViewStyle().setVerticalLabelsColor(Color.RED);
I created a custom SurfaceView called CaptureView and tried to add it into main.xml file:
<dev.recorder.client.CaptureView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/capturePreview"/>
The application seems to work fine but if I switch from main.xml tab to Layout in Eclipse the text NullPointerException appears instead of layout preview.
In the Activity I binded the controls the following way:
setContentView(R.layout.main);
bindControls();
private void bindControls()
{
videoPreview = (CaptureView)findViewById(R.id.capturePreview);
txtstatus = (TextView)findViewById(R.id.txtMode);
txtTimer = (TextView)findViewById(R.id.txtTime);
}
Does anyone know how this issue could be solved?
make sure that you are initializing the view in onFinishInflate and not in the constructor.
the layout preview code might initialize your control through a different code path.