I created glow effect imageview application. its working fine, my problem is glow effect left,right,bottom,top was little bit hiding so i am trying to set padding but still i have same problem. how to solve this problem?
code:
ImageView mImageBk = (ImageView)itemTemplate.findViewById(R.id.imgBk);
RelativeLayout.LayoutParams ImgBKLayoutParams = new RelativeLayout.LayoutParams(scrWidth/8 + scrWidth/20, scrWidth/8 + scrWidth/20 );
ImgBKLayoutParams.leftMargin =0;
ImgBKLayoutParams.topMargin = 0;
mImageBk.setLayoutParams(ImgBKLayoutParams);
mImageBk.setImageResource(R.drawable.glow_effect);
mImageBk.setPadding(10, 10, 10, 10);
mImageBk.setVisibility(View.GONE);
full code :
public class tttAdapter extends BaseAdapter{
private Context mContext;
private int scrWidth=0;
private int scrHeight=0;
private int scrDpi = 0;
private boolean setInvisible = false;
private boolean visibleConf[];
private boolean selected[];
private boolean innerListView = false;
private int[] IMAGE_IDS = {
R.drawable.s_record, R.drawable.s_record
};
private String[] title = {
"Tv", "My Favorites List1"
};
private String[] detail = {
"Tv", "My Favorites List1"
};
public favoritesAdapter(Context context) {
mContext = context;
visibleConf = new boolean[IMAGE_IDS.length];
selected = new boolean[IMAGE_IDS.length];
}
public void updateImageSize(int width, int height, int dpi) {
scrWidth= width;
scrHeight = height;
scrDpi = dpi;
}
public void setTextVisible(int position){
if(IMAGE_IDS.length <= position)
return;
for(int i=0; i < IMAGE_IDS.length; i++) {
visibleConf[i] = false;
}
visibleConf[position] = true;
}
public int getCount() {
return IMAGE_IDS.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public void setTextInvisible(int position) {
visibleConf[position] = false;
}
public void setInnerViewVisible(boolean enable) {
innerListView = enable;
}
public void unsetSelectedItem(int position) {
for(int i=0; i < IMAGE_IDS.length; i++) {
selected[i] = false;
}
}
public void setSelectedItem(int position) {
for(int i=0; i < IMAGE_IDS.length; i++) {
selected[i] = false;
}
selected[position] = true;
}
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View itemTemplate = inflater.inflate(R.layout.list_item, null);
ImageView mImageBk = (ImageView)itemTemplate.findViewById(R.id.imgBk);
RelativeLayout.LayoutParams ImgBKLayoutParams = new RelativeLayout.LayoutParams(scrWidth/8 + scrWidth/20, scrWidth/8 + scrWidth/20 );
ImgBKLayoutParams.leftMargin =0;
ImgBKLayoutParams.topMargin = 0;
mImageBk.setLayoutParams(ImgBKLayoutParams);
mImageBk.setImageResource(R.drawable.glow_effect);
mImageBk.setPadding(10, 10, 10, 10);
mImageBk.setVisibility(View.GONE);
ImageView mImage = (ImageView)itemTemplate.findViewById(R.id.img);
RelativeLayout.LayoutParams ImgLayoutParams = new RelativeLayout.LayoutParams(scrWidth/8 , scrWidth/8 );
ImgLayoutParams.leftMargin = scrWidth/38;
ImgLayoutParams.topMargin = scrWidth/38;
mImage.setLayoutParams(ImgLayoutParams);
mImage.setImageResource(IMAGE_IDS[position]);
mImage.bringToFront();
TextView mTextTitle = (TextView)itemTemplate.findViewById(R.id.title);
mTextTitle.setClickable(false);
mTextTitle.setEnabled(true);
mTextTitle.setText(title[position]);
TextView mTextDetail = (TextView)itemTemplate.findViewById(R.id.detail);
mTextDetail.setClickable(false);
mTextDetail.setEnabled(true);
mTextDetail.setText(detail[position]);
if(selected[position] == true) {
ImageView mArrowImg = (ImageView)itemTemplate.findViewById(R.id.imgArrow);
//mArrowImg.setLayoutParams(new RelativeLayout.LayoutParams(scrWidth/32, scrHeight/32));
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(scrWidth/32, scrHeight/32);
layoutParams.leftMargin = scrWidth / 8;
layoutParams.topMargin = scrWidth / 16;
mArrowImg.setLayoutParams(layoutParams);
mArrowImg.setImageResource(R.drawable.arrow);
mImage.setBackgroundResource(R.drawable.test_glowb);
mTextTitle.setVisibility(View.GONE);
mTextDetail.setVisibility(View.GONE);
mImageBk.setVisibility(View.VISIBLE);
} else {
if(innerListView == true) {
mImage.setVisibility(View.GONE);
}
}
if(visibleConf[position] == true) {
mTextTitle.setTextSize((scrWidth*160) / (30 * scrDpi));
mTextDetail.setTextSize((scrWidth*160) / (50 * scrDpi));
mTextTitle.setTypeface(null,Typeface.BOLD);
mTextDetail.setTypeface(null,Typeface.BOLD);
mImageBk.setVisibility(View.VISIBLE);
} else {
mTextTitle.setTextSize((scrWidth*160) / (40 * scrDpi));
mTextDetail.setTextSize((scrWidth*160) / (70 * scrDpi));
//mTextTitle.setVisibility(View.GONE);
//mTextDetail.setVisibility(View.GONE);
mImage.setAlpha(150);
}
if(innerListView == true) {
mTextTitle.setVisibility(View.GONE);
mTextDetail.setVisibility(View.GONE);
}
return itemTemplate;
}
}
xml:
<?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="wrap_content"
android:orientation="horizontal" >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
<ImageView
android:id="#+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="#+id/imgBk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="14dip"
android:layout_marginTop="30dp"
android:layout_centerInParent="true"
android:layout_toRightOf="#+id/thumb"
android:orientation="vertical" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumb"
android:layout_toRightOf="#+id/thumb"
android:layout_centerVertical="true"
android:textColor="#ffffff" />
<TextView
android:id="#+id/detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/thumb"
android:layout_alignParentBottom="true"
android:textColor="#ffffff" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgArrow"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</LinearLayout>
</RelativeLayout>
Be sure that you are setting margins/padding for the imageview widget as opposed to the layout container.
i think you want margins and not padding (for the imageView) , since padding puts spaces in the content of the view , meaning less space to show anything.
margins are outside of the view.
Related
I want to make chart like samsung health, support scrolling and center selected item. I'm using this library https://github.com/PhilJay/MPAndroidChart . But only works in tap, I don't have any idea how to configure it for scrolling.
I want something like this (look at black circle) :
Samsung Health Chart
Url Video : https://www.youtube.com/watch?v=_rcJraCzdNw
Image :
Samsung chart, centered selected item when tap or scrolling
My Chart
But My Chart look like this.
Url Video : https://www.youtube.com/watch?v=ZQGj4CcBygU
Image :
My Chart, centered selected item when tap-only, not in scrolling.
I tried onChartGestureEnd() inside setOnGestureListener(), but the position x is the location my finger first touch the screen. Example: let's say i swipe right (left to right) my finger first touch is 18, and the center position will be item 14. I want get that item 14 position, but don't know how to do it. I thought deceleration, so I call stopDeceleration(), but not works.
I also tried with ViewPager but also failed :(
#Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
MPPointD pointD = MPPointD.getInstance(0,0);
Transformer transformer = mChartOne.getTransformer(AxisDependency.LEFT);
transformer.getValuesByTouchPoint(me.getX(), me.getY(), pointD);
int roundX = round((float) pointD.x);
int roundY = round((float) pointD.y);
mChartOne.centerViewToAnimated(roundX, roundY, AxisDependency.LEFT, 200);
Utils.selectedIndex = roundX;
showSelectedInfo(roundX);
}
This is my code for this activity (Please ignore variable *Two) :
BarChartActivity.java
public class BarChartActivity extends AppCompatActivity {
private BarChart mChartOne;
private BarChart mChartTwo;
private Spinner mSpOption;
private TextView mTvDate;
private TextView mTvPower;
private TextView mTvCost;
private Legend lOne;
private Legend lTwo;
private LimitLine llOne;
private LimitLine llTwo;
private XAxis xAxisOne;
private XAxis xAxisTwo;
private YAxis leftAxisOne;
private YAxis leftAxisTwo;
private YAxis rightAxisOne;
private YAxis rightAxisTwo;
private ArrayList<BarEntry> barValuesOne = new ArrayList<>();
private ArrayList<BarEntry> barValuesTwo = new ArrayList<>();
private List<String> axisLabelOne = new ArrayList<>();
private List<String> axisLabelTwo = new ArrayList<>();
private List<Statistic> statisticList = new ArrayList<>();
private List<String> option = new ArrayList<>();
private String TAG = "bebe";
private String[] dummyCost;
private String[] dummyPower;
private String[] dummyDate;
private int lastIndex;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_be_chart);
setTitle("BarChartActivity");
//todo : create another layout for different dpi
mChartOne = findViewById(R.id.chart1);
mChartTwo = findViewById(R.id.chart2);
mSpOption = findViewById(R.id.sp_option);
mTvDate = findViewById(R.id.tv_date);
mTvPower = findViewById(R.id.tv_power);
mTvCost = findViewById(R.id.tv_cost);
option.add("Days");
option.add("Week");
option.add("Month");
dummyCost = getResources().getStringArray(R.array.dummy_cost);
dummyDate = getResources().getStringArray(R.array.dummy_date);
dummyPower = getResources().getStringArray(R.array.dummy_power);
int lastNum = 0;
for (int i = 0; i < dummyPower.length; i++) {
Statistic stat = new Statistic();
stat.cost = dummyCost[i];
stat.date = dummyDate[i];
stat.power = dummyPower[i];
statisticList.add(stat);
String numberStr = stat.date.substring(8,10);
int numStr = Integer.parseInt(numberStr); // remove 0, 01 -> 1
axisLabelOne.add(String.valueOf(numStr));
lastNum = numStr;
}
// empty label
for (int i = 0; i < 3; i++) {
lastNum++;
if (lastNum > 31) lastNum = 1;
axisLabelOne.add(String.valueOf(lastNum));
}
axisLabelTwo = new ArrayList<>(Arrays.asList(getResources().getStringArray(R.array.label_hour)));
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, option);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpOption.setAdapter(dataAdapter);
mSpOption.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
barValuesOne.clear();
mChartOne.animateY(500);
setDataOne();
mChartOne.setVisibleXRangeMaximum(7);
BarEntry lastEntry = barValuesOne.get(lastIndex);
Utils.selectedIndex = lastEntry.getX();
showSelectedInfo(lastIndex);
mChartOne.centerViewToAnimated(lastEntry.getX(), lastEntry.getY(),
AxisDependency.LEFT, 0);
mChartOne.invalidate();
barValuesTwo.clear();
mChartTwo.animateY(500);
setDataTwo();
mChartTwo.invalidate();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
loadChartOne();
loadChartTwo();
}
private void loadChartOne(){
mChartOne.setDrawBarShadow(false);
mChartOne.setDrawValueAboveBar(true);
mChartOne.getDescription().setEnabled(false);
mChartOne.setPinchZoom(false);
mChartOne.setDrawGridBackground(false);
mChartOne.setDragEnabled(true);
mChartOne.setScaleEnabled(false);
mChartOne.setPinchZoom(false);
mChartOne.setDoubleTapToZoomEnabled(false);
mChartOne.setDrawBorders(false);
mChartOne.setExtraOffsets(0f,
getResources().getDimensionPixelSize(R.dimen.padding_label),
0f,
getResources().getDimensionPixelSize(R.dimen.padding_label));
mChartOne.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
#Override
public void onValueSelected(Entry e, Highlight h) {
if (e == null)
return;
Log.e(TAG, "onValueSelected: "+e);
Log.e(TAG, "data: "+ axisLabelOne.get((int) e.getX()));
mChartOne.centerViewToAnimated(e.getX(), e.getY(),
mChartOne.getData().getDataSetByIndex(h.getDataSetIndex())
.getAxisDependency(), 200);
Utils.selectedIndex = e.getX();
showSelectedInfo((int) e.getX());
}
#Override
public void onNothingSelected() {
}
});
mChartOne.setOnChartGestureListener(new OnChartGestureListener() {
#Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
}
#Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
MPPointD pointD = MPPointD.getInstance(0,0);
Transformer transformer = mChartOne.getTransformer(AxisDependency.LEFT);
transformer.getValuesByTouchPoint(me.getX(), me.getY(), pointD);
int roundX = round((float) pointD.x);
int roundY = round((float) pointD.y);
mChartOne.centerViewToAnimated(roundX, roundY, AxisDependency.LEFT, 200);
Utils.selectedIndex = roundX;
showSelectedInfo(roundX);
}
#Override
public void onChartLongPressed(MotionEvent me) {
}
#Override
public void onChartDoubleTapped(MotionEvent me) {
}
#Override
public void onChartSingleTapped(MotionEvent me) {
}
#Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
#Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
#Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
}
});
ValueFormatter xAxisFormatter = new IndexAxisValueFormatter(axisLabelOne);
xAxisOne = mChartOne.getXAxis();
xAxisOne.setPosition(XAxisPosition.BOTTOM);
xAxisOne.setTextSize(16f);
xAxisOne.setGranularity(1f); // only intervals of 1 day
xAxisOne.setLabelCount(7);
xAxisOne.setValueFormatter(xAxisFormatter);
xAxisOne.setDrawGridLines(false);
xAxisOne.setDrawAxisLine(false);
xAxisOne.customLabel = true;
xAxisOne.setYOffset(getResources().getDimensionPixelSize(R.dimen.padding_label));
ValueFormatter custom = new MyValueFormatter(" W");
leftAxisOne = mChartOne.getAxisLeft();
leftAxisOne.setLabelCount(8, false);
leftAxisOne.setValueFormatter(custom);
leftAxisOne.setPosition(YAxisLabelPosition.OUTSIDE_CHART);
leftAxisOne.setSpaceTop(15f);
leftAxisOne.setAxisMinimum(1f); // this replaces setStartAtZero(true)
leftAxisOne.setEnabled(false);
llOne = new LimitLine(16f, "Usage warning (16 W)");
llOne.setLineColor(Color.RED);
llOne.setLineWidth(1f);
llOne.setTextColor(Color.BLACK);
llOne.setTextSize(12f);
llOne.enableDashedLine(4, 3, 0);
rightAxisOne = mChartOne.getAxisRight();
rightAxisOne.setDrawGridLines(true);
rightAxisOne.setLabelCount(2, false);
rightAxisOne.setValueFormatter(custom);
rightAxisOne.setSpaceTop(15f);
rightAxisOne.setAxisMinimum(1f); // this replaces setStartAtZero(true)
rightAxisOne.setCenterAxisLabels(true);
rightAxisOne.setPosition(YAxisLabelPosition.INSIDE_CHART);
rightAxisOne.enableGridDashedLine(4, 3, 0);
rightAxisOne.setGridColor(ContextCompat.getColor(this, R.color.bar_color));
rightAxisOne.addLimitLine(llOne);
rightAxisOne.setDrawLimitLinesBehindData(false);
rightAxisOne.setDrawZeroLine(false);
rightAxisOne.setDrawAxisLine(false);
lOne = mChartOne.getLegend();
lOne.setEnabled(false);
}
private void loadChartTwo(){
mChartTwo.setDrawBarShadow(false);
mChartTwo.setDrawValueAboveBar(false);
mChartTwo.getDescription().setEnabled(false);
mChartTwo.setPinchZoom(false);
mChartTwo.setDrawGridBackground(false);
mChartTwo.setDragEnabled(false);
mChartTwo.setScaleEnabled(false);
mChartTwo.setPinchZoom(false);
mChartTwo.setDoubleTapToZoomEnabled(false);
mChartTwo.setDrawBorders(false);
mChartTwo.setExtraOffsets(0f,
getResources().getDimensionPixelSize(R.dimen.padding_label),
0f,
getResources().getDimensionPixelSize(R.dimen.padding_label));
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
mv.setChartView(mChartTwo); // For bounds control
mChartTwo.setMarker(mv); // Set the marker to the chart
ValueFormatter xAxisFormatter = new IndexAxisValueFormatter(axisLabelTwo);
xAxisTwo = mChartTwo.getXAxis();
xAxisTwo.setPosition(XAxisPosition.BOTTOM);
xAxisTwo.setTextSize(10f);
xAxisTwo.setValueFormatter(xAxisFormatter);
xAxisTwo.setDrawGridLines(false);
xAxisTwo.setDrawAxisLine(true);
xAxisTwo.setLabelCount(5);
xAxisTwo.customLabel = false;
leftAxisTwo = mChartTwo.getAxisLeft();
leftAxisTwo.setAxisMinimum(1f);
leftAxisTwo.setEnabled(false);
rightAxisTwo = mChartTwo.getAxisRight();
rightAxisTwo.setAxisMinimum(1f);
rightAxisTwo.setEnabled(false);
lTwo = mChartTwo.getLegend();
lTwo.setEnabled(false);
}
private void setDataOne() {
// start empty space
Utils.unselectedIndex[0] = 0f;
Utils.unselectedIndex[1] = 1f;
Utils.unselectedIndex[2] = 2f;
Utils.firstSelectedIndex = 3f;
barValuesOne.add(new BarEntry(Utils.unselectedIndex[0], 0));
barValuesOne.add(new BarEntry(Utils.unselectedIndex[1], 0));
barValuesOne.add(new BarEntry(Utils.unselectedIndex[2], 0));
float start = Utils.firstSelectedIndex;
float tmpStart = start;
for (int i = (int) start; i < dummyPower.length; i++) {
tmpStart = i;
lastIndex = i;
float val = Float.parseFloat(dummyPower[i]);
barValuesOne.add(new BarEntry(i, val));
Utils.lastSelectedIndex = i;
}
// end empty space
barValuesOne.add(new BarEntry(++tmpStart, 0));
Utils.unselectedIndex[3] = tmpStart;
barValuesOne.add(new BarEntry(++tmpStart, 0));
Utils.unselectedIndex[4] = tmpStart;
barValuesOne.add(new BarEntry(++tmpStart, 0));
Utils.unselectedIndex[5] = tmpStart;
BarDataSet set1;
if (mChartOne.getData() != null &&
mChartOne.getData().getDataSetCount() > 0) {
set1 = (BarDataSet) mChartOne.getData().getDataSetByIndex(0);
set1.setValues(barValuesOne);
mChartOne.getData().notifyDataChanged();
mChartOne.notifyDataSetChanged();
} else {
set1 = new BarDataSet(barValuesOne, "The year 2017");
set1.setDrawIcons(false);
set1.setColor(ContextCompat.getColor(this, R.color.bar_color));
set1.setHighLightColor(ContextCompat.getColor(this, R.color.bar_color));
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(8f);
data.setBarWidth(0.2f);
mChartOne.setData(data);
}
}
private void setDataTwo() {
float start = 0f;
int count = 24;
int range = 20;
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
for (int i = (int) start; i < start + count; i++) {
float val = (float) (Math.random() * (range + 1));
if (val < 4) val += 6.5;
if (i < hour) barValuesTwo.add(new BarEntry(i, val));
else barValuesTwo.add(new BarEntry(i, 0));
}
BarDataSet set1;
if (mChartTwo.getData() != null &&
mChartTwo.getData().getDataSetCount() > 0) {
set1 = (BarDataSet) mChartTwo.getData().getDataSetByIndex(0);
set1.setValues(barValuesTwo);
set1.setDrawValues(false);
mChartTwo.getData().notifyDataChanged();
mChartTwo.notifyDataSetChanged();
} else {
set1 = new BarDataSet(barValuesTwo, "The year 2017");
set1.setDrawIcons(false);
set1.setDrawValues(false);
set1.setColor(ContextCompat.getColor(this, R.color.bar_hour_color));
set1.setHighLightColor(ContextCompat.getColor(this, R.color.bar_hour_color));
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(12f);
data.setBarWidth(0.2f);
mChartTwo.setData(data);
}
}
private final RectF onValueSelectedRectF = new RectF();
private void showSelectedInfo(int position){
boolean unselected = false;
for (int i = 0; i < Utils.unselectedIndex.length; i++) {
if (position == Utils.unselectedIndex[i]) {
unselected = true;
break;
}
}
if (!unselected && position == Utils.selectedIndex) {
Statistic stat = statisticList.get(position);
setTextData(stat);
} else if (unselected){
if (position > Utils.lastSelectedIndex ||
position < Utils.firstSelectedIndex){
if ((position <= Utils.firstSelectedIndex)){
Statistic stat = statisticList.get((int) Utils.firstSelectedIndex);
setTextData(stat);
} else if ((position >= Utils.lastSelectedIndex)) {
Statistic stat = statisticList.get((int) Utils.lastSelectedIndex);
setTextData(stat);
}
}
}
}
private void setTextData(Statistic stat){
int cost = Integer.parseInt(stat.cost);
String thousandCost = NumberFormat.getNumberInstance(Locale.GERMAN).format(cost);
mTvDate.setText(getDateString(stat.date));
mTvPower.setText(stat.power + " W");
mTvCost.setText("(Rp "+thousandCost+")");
}
private String getDateString(String rawDate) {
String date = rawDate.replace("-","").substring(0, 8);
String year = date.substring(0,4);
String month = date.substring(4,6);
String day = date.substring(6,8);
String monthName = getMonthName(month);
return String.valueOf(new StringBuilder().append(day).append(" ").append(monthName)
.append(" ").append(year));
}
private String getMonthName(String data) {
int month = Integer.parseInt(data);
String[] monthName = {"Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli",
"Agustus", "September", "Oktober", "November", "Desember"};
return monthName[month-1];
}
public int round(float f) {
int c = (int) ((f) + 0.5f);
float n = f + 0.5f;
return (n - c) % 2 == 0 ? (int) f : c;
}
}
This is my layout :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_below="#id/chart1"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#e1e1e1"
android:layout_marginTop="-48dp"
android:layout_centerHorizontal="true">
<View
android:id="#+id/v_selected_label"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_centerInParent="true"
android:background="#drawable/selected_bar_label"/>
<View
android:id="#+id/v_tooltip"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:background="#drawable/tooltip"/>
</RelativeLayout>
<com.github.mikephil.charting.charts.BarChart
android:id="#+id/chart1"
android:layout_width="match_parent"
android:layout_height="240dp"
android:padding="0dp"
android:layout_marginTop="16dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"/>
<Spinner
android:id="#+id/sp_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="#android:color/white"/>
</RelativeLayout>
<TextView
android:id="#+id/tv_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:textSize="16sp"
tools:text="24 Januari 2019" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp"
android:layout_gravity="center">
<TextView
android:id="#+id/tv_power"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
tools:text="27 W" />
<TextView
android:id="#+id/tv_cost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginStart="8dp"
tools:text="(Rp 5000)" />
</LinearLayout>
<TextView
android:id="#+id/tv_last_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:text="#string/dummy_last_update" />
<com.github.mikephil.charting.charts.BarChart
android:id="#+id/chart2"
android:layout_width="match_parent"
android:layout_height="240dp"
android:padding="0dp"
android:layout_marginTop="16dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="16dp"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="#string/label"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginTop="8dp"
android:textColor="#android:color/black"
android:text="#string/power_plug"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_marginTop="8dp"
android:src="#drawable/underline_statistic"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_marginTop="16dp"
android:text="#string/total_time"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginTop="8dp"
android:textColor="#android:color/black"
android:text="#string/dummy_total_time"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_marginTop="8dp"
android:src="#drawable/underline_statistic"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
I expect my chart support for scrolling too, not only tap.
I have the background of the GridView which is Transparent to its main layout. The List Item Should also have the background transparent , but the Seperator should have different Color .How can this be Achieved?
Main Container(image drawable is setted through progamatically)
<*************.AutoGridView
android:id="#+id/dashMenu"
android:layout_width="match_parent"
android:layout_height="210dp"
android:layout_alignParentBottom="true"
android:background="#android:color/transparent"
android:horizontalSpacing="1dp"
android:numColumns="#integer/grid_columns"
android:scrollbars="none"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp"
android:visibility="visible" />
items
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/menuWrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="12dp"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="#+id/menuImg"
android:layout_width="58dp"
android:layout_height="58dp"
android:padding="8dp"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/menuLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/montserrat_regular"
android:gravity="center_horizontal"
android:paddingBottom="6dp"
android:text="Menu Item"
android:textColor="#color/white"
android:textSize="12sp" />
</LinearLayout>
</RelativeLayout>
Adapter
public class HomeMenuAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Menu> menus;
public HomeMenuAdapter(Context context, ArrayList<Menu> menus) {
mContext = context;
this.menus = menus;
}
#Override
public int getCount() {
return menus.size();
}
#Override
public Menu getItem(int position) {
return menus.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
Menu menu = menus.get(position);
ImageView menuImage;
TextView menuLabel;
View v;
if (convertView == null) {
v = layoutInflater.inflate(R.layout.dash_menu_item, null);
} else {
v = convertView;
}
/*int columns = 3;
int total = menus.size();
int rows = total / columns;
LinearLayout menuWrapper = v.findViewById(R.id.menuWrapper);
if (((position + 1) % columns) == 0) {
if((total - position) > columns ) {
CommonUtils.setDrawableBackground(mContext, menuWrapper, R.drawable.menu_border_bottom);
} else {
CommonUtils.setDrawableBackground(mContext, menuWrapper, R.drawable.menu_border_neutral);
}
} else if((total - position) > columns ) {
CommonUtils.setDrawableBackground(mContext, menuWrapper, R.drawable.menu_border_right_bottom);
} else {
CommonUtils.setDrawableBackground(mContext, menuWrapper, R.drawable.menu_border_right);
}
*/
menuImage = v.findViewById(R.id.menuImg);
menuLabel = v.findViewById(R.id.menuLabel);
if(menu.getIcon() != null && !TextUtils.isEmpty(menu.getIcon()) &&
URLUtil.isValidUrl(menu.getIcon())) {
RequestOptions requestOptions = new RequestOptions();
requestOptions.error(menu.getIconId());
Glide.with(menuImage).applyDefaultRequestOptions(requestOptions)
.load(menu.getIcon()).into(menuImage);
} else if(menu.getIconId() != 0) {
setImage(menuImage, menu.getIconId());
}
menuLabel.setText(menu.getName());
v.setOnClickListener(new OnOneClickListener() {
#Override
public void onOneClick(View v) {
new Router(mContext).route(menu);
}
});
return v;
}
private void setImage(ImageView menuImage, int iconId) {
menuImage.setImageDrawable(mContext.getResources().getDrawable(
iconId));
}
}
AutoGridView
public class AutoGridView extends GridView {
private static final String TAG = "AutoGridView";
private int numColumnsID;
private int previousFirstVisible;
private int numColumns = 1;
public AutoGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public AutoGridView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public AutoGridView(Context context) {
super(context);
}
/**
* Sets the numColumns based on the attributeset
*/
private void init(AttributeSet attrs) {
// Read numColumns out of the AttributeSet
int count = attrs.getAttributeCount();
if(count > 0) {
for(int i = 0; i < count; i++) {
String name = attrs.getAttributeName(i);
if(name != null && name.equals("numColumns")) {
// Update columns
this.numColumnsID = attrs.getAttributeResourceValue(i, 1);
updateColumns();
break;
}
}
}
Log.d(TAG, "numColumns set to: " + numColumns);
}
/**
* Reads the amount of columns from the resource file and
* updates the "numColumns" variable
*/
private void updateColumns() {
this.numColumns = getContext().getResources().getInteger(numColumnsID);
}
#Override
public void setNumColumns(int numColumns) {
this.numColumns = numColumns;
super.setNumColumns(numColumns);
Log.d(TAG, "setSelection --> " + previousFirstVisible);
setSelection(previousFirstVisible);
}
#Override
protected void onLayout(boolean changed, int leftPos, int topPos, int rightPos, int bottomPos) {
super.onLayout(changed, leftPos, topPos, rightPos, bottomPos);
setHeights();
}
#Override
protected void onConfigurationChanged(Configuration newConfig) {
updateColumns();
setNumColumns(this.numColumns);
}
#Override
protected void onScrollChanged(int newHorizontal, int newVertical, int oldHorizontal, int oldVertical) {
// Check if the first visible position has changed due to this scroll
int firstVisible = getFirstVisiblePosition();
if(previousFirstVisible != firstVisible) {
// Update position, and update heights
previousFirstVisible = firstVisible;
setHeights();
}
super.onScrollChanged(newHorizontal, newVertical, oldHorizontal, oldVertical);
}
/**
* Sets the height of each view in a row equal to the height of the tallest view in this row.
*/
private void setHeights() {
ListAdapter adapter = getAdapter();
if(adapter != null) {
for(int i = 0; i < getChildCount(); i+=numColumns) {
// Determine the maximum height for this row
int maxHeight = 0;
for(int j = i; j < i+numColumns; j++) {
View view = getChildAt(j);
if(view != null && view.getHeight() > maxHeight) {
maxHeight = view.getHeight();
}
}
//Log.d(TAG, "Max height for row #" + i/numColumns + ": " + maxHeight);
// Set max height for each element in this row
if(maxHeight > 0) {
for(int j = i; j < i+numColumns; j++) {
View view = getChildAt(j);
if(view != null && view.getHeight() != maxHeight) {
view.setMinimumHeight(maxHeight);
}
}
}
}
}
}
}
Do not Suggest adding extra view(please).
Please refer to
How can a divider line be added in an Android RecyclerView?
You have to change the item decorator color as u desire
Can anyone please suggest how to implement the following in my droid app?
I've created a custom gallery, and when an image is selected, I show a preview of the image exactly like instagram. Now when I scoll up, I need some 20% of the image view to stick to the top like this:
I'm right now using, Observablegrid view, which is of not that much use!
Please suggest any ideas. Thanks!
Here is my answer using the same Observablegridview, which got to work after some analysis and modifications while scrolling the grid.
For the grid of image to be displayed, use this ObservableGridView.java
Here is the xml layout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/mainFrame">
<com.sampleapp.Observablescroll.ObservableGridView
android:id="#+id/camera_gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:numColumns="4" />
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/gallery_lay"
android:layout_width="wrap_content"
android:layout_height="365dp"
android:background="#color/black"
android:orientation="vertical">
<com.fenchtose.nocropper.CropperImageView
android:id="#+id/gallery_click_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
app:grid_color="#color/action_bar_color" />
</RelativeLayout>
<View
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="300dp" />
</RelativeLayout>
</FrameLayout>
In your java class, implement ObservableScrollViewCallbacks
mHeaderView = (RelativeLayout) rootview.findViewById(R.id.header);
mToolbarView = rootview.findViewById(R.id.toolbar);
camera_gridView = (ObservableGridView) rootview.findViewById(R.id.camera_gridView);
LayoutInflater inflaters = LayoutInflater.from(getActivity());
camera_gridView.addHeaderView(inflaters.inflate(R.layout.image_holder_view, camera_gridView, false));
// view that leaves 300dp space to display the selected image from the grid
camera_gridView.addHeaderView(inflaters.inflate(R.layout.sticky_tool_bar_view, camera_gridView, false));
// a sticky view with action bar's height, so that the grid doesn't scroll above this
camera_gridView.setScrollViewCallbacks(this);
//overridden methods
#Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
if (dragging) {
int toolbarHeight = mToolbarView.getHeight();
// int toolbarHeight = 300;
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
if (firstScroll) {
float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (-toolbarHeight < currentHeaderTranslationY) {
mBaseTranslationY = scrollY;
}
}
float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
}
}
#Override
public void onDownMotionEvent() {
}
#Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
mBaseTranslationY = 0;
if (scrollState == ScrollState.DOWN) {
int toolbarHeight = mToolbarView.getHeight();
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
} else if (scrollState == ScrollState.UP) {
int toolbarHeight = mToolbarView.getHeight();
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
System.out.println("++++upif" + scrollY);
hideToolbar();
} else {
System.out.println("++++upelse" + scrollY);
showToolbar();
}
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
} else {
if (!toolbarIsShown() && !toolbarIsHidden()) {
showToolbar();
}
}
}
//method to show the toolbar
private void showToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (headerTranslationY != 0) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
}
}
//method to hide the toolbar
private void hideToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
int toolbarHeight = mToolbarView.getHeight();
if (headerTranslationY != -toolbarHeight) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
}
}
private boolean toolbarIsShown() {
return ViewHelper.getTranslationY(mHeaderView) == 0;
}
private boolean toolbarIsHidden() {
return ViewHelper.getTranslationY(mHeaderView) == -mToolbarView.getHeight();
}
<?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:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_below="#+id/mainFrame">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/gallery_lay"
android:layout_width="wrap_content"
android:layout_height="365dp"
android:background="#color/black"
android:orientation="vertical">
<com.fenchtose.nocropper.CropperView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff282828"
app:nocropper__grid_color="#color/colorAccent"
app:nocropper__grid_opacity="0.8"
app:nocropper__grid_thickness="0.8dp"
app:nocropper__padding_color="#color/colorAccent" />
</RelativeLayout>
</RelativeLayout>
<com.myapp.Util.ObservableGridView
android:id="#+id/camera_gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:numColumns="4" />
</FrameLayout>
And below is java implementation
public class GalleryFragmentTest2 extends Fragment implements View.OnClickListener, ImageGridItemListner, ObservableScrollViewCallbacks {
private static final String TAG = "GalleryFragment";
CropperView mImageView;
RecyclerView recImgHolder;
CoordinatorLayout container;
AppBarLayout app_bar_main;
private Bitmap originalBitmap;
private Bitmap mBitmap;
private boolean isSnappedToCenter = false;
private int rotationCount = 0;
//constants
private static final int NUM_GRID_COLUMNS = 4;
//widgets
private GridView gridView;
private ImageView galleryImage;
private Spinner directorySpinner;
//vars
private ArrayList<Model_images> directories;
private String mAppend = "file://";
private String mSelectedImage;
RelativeLayout mHeaderView, relCropperView;
ObservableGridView camera_gridView;
private int mBaseTranslationY;
private void initImageLoader() {
UniversalImageLoader universalImageLoader = new UniversalImageLoader(getContext());
ImageLoader.getInstance().init(universalImageLoader.getConfig());
}
#SuppressLint("ClickableViewAccessibility")
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.gallery_test2, container, false);
mHeaderView = (RelativeLayout) view.findViewById(R.id.header);
View mToolbarView = view.findViewById(R.id.toolbar);
camera_gridView = (ObservableGridView) view.findViewById(R.id.camera_gridView);
LayoutInflater inflaters = LayoutInflater.from(getActivity());
View view1 = inflaters.inflate(R.layout.snippet_top_gallerytoolbar,camera_gridView,false);
View view2 = inflaters.inflate(R.layout.rec_img_test,camera_gridView,false);
camera_gridView.addHeaderView(inflaters.inflate(R.layout.snippet_top_gallerytoolbar,camera_gridView,false));
// view that leaves 300dp space to display the selected image from the grid
camera_gridView.addHeaderView(inflaters.inflate(R.layout.rec_img_test,camera_gridView,false));
// a sticky view with action bar's height, so that the grid doesn't scroll above this
camera_gridView.setScrollViewCallbacks(this);
mImageView = (CropperView) view.findViewById(R.id.imageview);
recImgHolder = view2.findViewById(R.id.recImgHolder);
LinearLayoutManager manager = new GridLayoutManager(getActivity(), 4);
recImgHolder.setLayoutManager(manager);
recImgHolder.setHasFixedSize(true);
recImgHolder.setItemViewCacheSize(20);
recImgHolder.setDrawingCacheEnabled(true);
recImgHolder.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
TextView nextScreen = (TextView) view.findViewById(R.id.tvNext);
directorySpinner = (Spinner) view1.findViewById(R.id.spinnerDirectory);
directories = new ArrayList<>();
Log.d(TAG, "onCreateView: started.");
initImageLoader();
init();
mImageView.setDebug(true);
mImageView.setGestureEnabled(true);
mImageView.setGridCallback(new CropperView.GridCallback() {
#Override
public boolean onGestureStarted() {
return true;
}
#Override
public boolean onGestureCompleted() {
return false;
}
});
return view;
}
private void init() {
try {
FilePaths filePaths = new FilePaths();
directories = new ArrayList<>();
//check for other folders indide "/storage/emulated/0/pictures"
directories = FileSearch.fn_imagespath(Objects.requireNonNull(getContext()), filePaths.PICTURES);
ArrayList<String> directoryNames = new ArrayList<>();
for (int i = 0; i < directories.size(); i++) {
int index = directories.get(i).getStr_folder().lastIndexOf("/");
String string = directories.get(i).getStr_folder().substring(index + 1);
directoryNames.add(string);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, directoryNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
directorySpinner.setAdapter(adapter);
directorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemClick: selected: " + directories.get(position));
//setup our image grid for the directory chosen
setupGridView(directories.get(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}catch (Exception e){
e.printStackTrace();
}
}
private void setupGridView(Model_images selectedDirectory) {
try {
final ArrayList<String> imgURLs = selectedDirectory.getAl_imagepath();
//use the grid adapter to adapter the images to gridview
GridImageAdapter adapter = new GridImageAdapter(getActivity(), R.layout.layout_grid_imageview, mAppend, imgURLs, (ImageGridItemListner) this);
adapter.setGridItemListner(this);
recImgHolder.setAdapter(adapter);
//set the first image to be displayed when the activity fragment view is inflated
try {
setImage(imgURLs.get(0), mAppend);
} catch (ArrayIndexOutOfBoundsException e) {
Log.e(TAG, "setupGridView: ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getActivity(), ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void setImage(String imgURL, String append) {
Log.d(TAG, "setImage: setting image");
ImageLoader imageLoader = ImageLoader.getInstance();
Bitmap bmp = imageLoader.loadImageSync(append + imgURL);
mImageView.setImageBitmap(bmp);
mBitmap = bmp;
originalBitmap = bmp;
}
private void rotateImage() {
if (mBitmap == null) {
Log.e(TAG, "bitmap is not loaded yet");
return;
}
mBitmap = BitmapUtils.rotateBitmap(mBitmap, 90);
mImageView.setImageBitmap(mBitmap);
rotationCount++;
}
private void snapImage() {
if (isSnappedToCenter) {
mImageView.cropToCenter();
} else {
mImageView.fitToCenter();
}
isSnappedToCenter = !isSnappedToCenter;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rotate_button:
rotateImage();
break;
case R.id.snap_button:
snapImage();
break;
}
}
#Override
public void onImageGridItemClick(String imgURL) {
try {
setImage(imgURL, mAppend);
} catch (ArrayIndexOutOfBoundsException e) {
Log.e(TAG, "setupGridView: ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}
//overridden methods
#Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
if (dragging) {
int toolbarHeight = mHeaderView.getHeight();
// int toolbarHeight = 300;
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
if (firstScroll) {
float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (-toolbarHeight < currentHeaderTranslationY) {
mBaseTranslationY = scrollY;
}
}
float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
}
}
#Override
public void onDownMotionEvent() {
}
#Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
mBaseTranslationY = 0;
if (scrollState == ScrollState.DOWN) {
int toolbarHeight = mHeaderView.getHeight();
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
} else if (scrollState == ScrollState.UP) {
int toolbarHeight = mHeaderView.getHeight();
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
System.out.println("++++upif" + scrollY);
hideToolbar();
} else {
System.out.println("++++upelse" + scrollY);
showToolbar();
}
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
} else {
if (!toolbarIsShown() && !toolbarIsHidden()) {
showToolbar();
}
}
}
//method to show the toolbar
private void showToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (headerTranslationY != 0) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
}
}
//method to hide the toolbar
private void hideToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
int toolbarHeight = mHeaderView.getHeight();
if (headerTranslationY != -toolbarHeight) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
}
}
private boolean toolbarIsShown() {
return ViewHelper.getTranslationY(mHeaderView) == 0;
}
private boolean toolbarIsHidden() {
return ViewHelper.getTranslationY(mHeaderView) == -mHeaderView.getHeight();
}
}
inflated headerview in observable is
layout :- snippet_top_gallerytoolbar
<android.support.design.widget.AppBarLayout android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.Toolbar
android:id="#+id/profileToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/ivCloseShare"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginEnd="20dp"
android:src="#drawable/ic_back" />
<Spinner
android:id="#+id/spinnerDirectory"
android:layout_width="#dimen/_120sdp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/ivCloseShare"
android:gravity="center_vertical"
android:text="Gallery"
android:textColor="#color/black"
android:textSize="20sp">
</Spinner>
<TextView
android:id="#+id/tvNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:text="#string/string_next"
android:textColor="#color/white"
android:textSize="20sp" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
second added headerview to observablegrid
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recImgHolder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
i am getting view like below
I found a couple of questions regarding rangebars (seekbars with two thumbs) on Android, like Android Seekbar with two thumbs or working with SeekBar with two thumbs. All the answers point to components that look quite outdated since Material Design and thus AppCompat was released.
What I'm looking for is a Rangebar that looks like the AppCompatSeekBar with two thumbs. Are there any available libraries or ways to hack into the platform SeekBar so that the available resources can be reused?
This is my first time answering something here.
I created my own custom rangebar as follows.
Create the following files.
RangeBar.java
public class RangeBar extends FrameLayout{
int minVal = 0;
int maxVal = 100;
Context context;
ImageView leftThumb;
ImageView rightThumb;
View view;
int leftThumbPos = 0;
int rightThumbPos = 100;
public RangeBar(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
this.view = inflate(getContext(), R.layout.range_seekbar, null);
addView(this.view);
}
public RangeBar(Context context){
super(context);
this.context = context;
this.view = inflate(getContext(), R.layout.range_seekbar, null);
addView(this.view);
}
public void create() {
leftThumb = (ImageView)findViewById(R.id.left_thumb);
rightThumb = (ImageView)findViewById(R.id.right_thumb);
final View leftBar = findViewById(R.id.left_bar);
final View rightBar = findViewById(R.id.right_bar);
final View middleBar = findViewById(R.id.middle_bar);
final LinearLayout.LayoutParams leftBarLayoutParams = (LinearLayout.LayoutParams) leftBar.getLayoutParams();
final LinearLayout.LayoutParams rightBarLayoutParams = (LinearLayout.LayoutParams) rightBar.getLayoutParams();
final LinearLayout.LayoutParams middleBarLayoutParams = (LinearLayout.LayoutParams) middleBar.getLayoutParams();
final LinearLayout llRangeSeekbar = (LinearLayout)findViewById(R.id.ll_range_seekbar);
((TextView)findViewById(R.id.tv_range_max)).setText(maxVal+"");
((TextView)findViewById(R.id.tv_range_min)).setText(minVal+"");
leftThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
rightThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");
leftThumb.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int diff = maxVal - minVal;
if(diff < 0){
diff = 100;
minVal = 0;
maxVal = 100;
}
float width = llRangeSeekbar.getWidth();
float gap = leftThumb.getWidth();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
leftThumb.bringToFront();
return true;
}else if (event.getAction() == MotionEvent.ACTION_MOVE ) {
float temp1 = leftBarLayoutParams.weight;
float temp2 = middleBarLayoutParams.weight;
leftBarLayoutParams.weight += event.getX()/width;
middleBarLayoutParams.weight = 1 - (leftBarLayoutParams.weight + rightBarLayoutParams.weight);
int tempMaxVal = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");
int tempMinVal = (int)(diff*leftBarLayoutParams.weight + minVal);
if(tempMinVal > tempMaxVal){
tempMinVal = tempMaxVal;
}
if(tempMinVal < minVal){
tempMinVal = minVal;
}
((TextView)findViewById(R.id.tv_range_min)).setText(tempMinVal + "");
if(middleBarLayoutParams.weight > gap/width && leftBarLayoutParams.weight >= 0){
leftBar.setLayoutParams(leftBarLayoutParams);
middleBar.setLayoutParams(middleBarLayoutParams);
}else {
if(leftBarLayoutParams.weight < 0){
leftBarLayoutParams.weight = 0;
middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);
}else{
middleBarLayoutParams.weight = gap/width + (tempMaxVal - tempMinVal)/(1.0f*diff);
leftBarLayoutParams.weight = 1 - (middleBarLayoutParams.weight + rightBarLayoutParams.weight);
}
leftBar.setLayoutParams(leftBarLayoutParams);
middleBar.setLayoutParams(middleBarLayoutParams);
}
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP) {
leftThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
return true;
}else
{
return false;
}
}
});
rightThumb.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int diff = maxVal - minVal;
if(diff < 0){
diff = 100;
minVal = 0;
maxVal = 100;
}
float width = llRangeSeekbar.getWidth();
float gap = leftThumb.getWidth();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
rightThumb.bringToFront();
return true;
}else if (event.getAction() == MotionEvent.ACTION_MOVE) {
float temp1 = middleBarLayoutParams.weight;
float temp2 = rightBarLayoutParams.weight;
rightBarLayoutParams.weight -= (event.getX()/width);
middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);
int tempMinVal = Integer.parseInt(((TextView)findViewById(R.id.tv_range_min)).getText()+"");
int tempMaxVal = (int)(diff*(1 - rightBarLayoutParams.weight) + minVal);
if(tempMaxVal < tempMinVal){
tempMaxVal = tempMinVal;
}
if(tempMaxVal > maxVal){
tempMaxVal = maxVal;
}
((TextView)findViewById(R.id.tv_range_max)).setText(tempMaxVal+"");
if(middleBarLayoutParams.weight > gap/width && rightBarLayoutParams.weight >= 0){
rightBar.setLayoutParams(rightBarLayoutParams);
middleBar.setLayoutParams(middleBarLayoutParams);
}else{
if(rightBarLayoutParams.weight < 0){
rightBarLayoutParams.weight = 0;
middleBarLayoutParams.weight = 1 - (rightBarLayoutParams.weight + leftBarLayoutParams.weight);
}else {
middleBarLayoutParams.weight = gap/width + (tempMaxVal - tempMinVal)/(1.0f*diff);
rightBarLayoutParams.weight = 1 - (leftBarLayoutParams.weight + middleBarLayoutParams.weight);
}
rightBar.setLayoutParams(rightBarLayoutParams);
middleBar.setLayoutParams(middleBarLayoutParams);
}
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP) {
rightThumbPos = Integer.parseInt(((TextView)findViewById(R.id.tv_range_max)).getText()+"");
return true;
}
else
{
return false;
}
}
});
}
public int getMinVal() {
return minVal;
}
public void setMinVal(int minVal) {
this.minVal = minVal;
}
public int getMaxVal() {
return maxVal;
}
public void setMaxVal(int maxVal) {
this.maxVal = maxVal;
}
public int getLeftThumbPos() {
return leftThumbPos;
}
public void setLeftThumbPos(int leftThumbPos) {
this.leftThumbPos = leftThumbPos;
}
public int getRightThumbPos() {
return rightThumbPos;
}
public void setRightThumbPos(int rightThumbPos) {
this.rightThumbPos = rightThumbPos;
}
}
and range_seekbar.xml
<?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:gravity="center"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:id="#+id/ll_range_seekbar"
android:layout_height="wrap_content">
<View
android:layout_width="0dp"
android:layout_weight="0"
android:id="#+id/left_bar"
android:background="#color/light_grey"
android:layout_height="1dp"/>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/middle_bar"
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_centerVertical="true"
android:id="#+id/middle_view"
android:layout_toRightOf="#+id/left_thumb"
android:layout_toLeftOf="#+id/right_thumb"
android:background="#color/color_select_sky_blue"
android:layout_height="1dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/left_thumb"
android:layout_alignParentLeft="true"
android:src="#drawable/seek_thumb_normal"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/right_thumb"
android:layout_alignParentRight="true"
android:src="#drawable/seek_thumb_normal"/>
</RelativeLayout>
<View
android:layout_width="0dp"
android:layout_weight="0"
android:id="#+id/right_bar"
android:background="#color/light_grey"
android:layout_height="1dp"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:id="#+id/tv_range_min"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/tv_range_max"/>
</RelativeLayout>
</LinearLayout>
Use them in the activity as follows.
Test.java
public class Test extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
RangeBar rangeBar = (RangeBar) findViewById(R.id.rangebar);
rangeBar.setMinVal(25);
rangeBar.setMaxVal(50);
rangeBar.create();
}
}.
This is the layout file for the activity.
test.xml
<?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:gravity="center"
android:layout_margin="50dp"
android:layout_height="match_parent">
<com.example.pankajkumar.Utils.RangeBar
android:id="#+id/rangebar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
I have a GridView with the following properties:
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/PhoneImageGrid"
style="#style/PhotoGridLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:alwaysDrawnWithCache="true"
android:clipChildren="true"
android:columnWidth="100dp"
android:horizontalSpacing="2dp"
android:numColumns="auto_fit"
android:padding="4dp"
android:scrollbars="none"
android:scrollingCache="true"
android:smoothScrollbar="true"
android:stretchMode="columnWidth"
android:verticalSpacing="4dp" />
Here is the grid item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/thumbImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<CheckBox
android:id="#+id/itemCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Now when when i run the app, i got a gridview, looks everything right in portrait and when i turn it to landscape the col width is being changed but i want the contents of the item also to be scaled proportionately according to the new col width(item_height = item_width = new col width). How can i achieve this? Thanks
Its bit tricky to set get the gridview col width. One you got the col width you can set the imageview height to the col width and notify adapter of changes. (code taken from the android samples: https://developer.android.com/training/displaying-bitmaps/index.html)
Here's the way to measure the col width:
imagegrid.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (imageAdapter.getNumColumns() == 0) {
final int numColumns = (int) Math.floor(imagegrid.getWidth()
/ (mImageThumbSize + mImageThumbSpacing));
if (numColumns > 0) {
final int columnWidth = (imagegrid.getWidth() / numColumns) - mImageThumbSpacing;
imageAdapter.setNumColumns(numColumns);
imageAdapter.setItemHeight(columnWidth);
}
}
}
});
Create these methods in the Adapter:
public void setNumColumns(int numColumns) {
mNumColumns = numColumns;
}
public int getNumColumns() {
return mNumColumns;
}
public void setItemHeight(int height) {
if (height == mItemHeight) {
return;
}
mItemHeight = height;
mImageViewLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight);
// mImageFetcher.setImageSize(height);
notifyDataSetChanged();
}
Set the initial image size as:
mImageViewLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
Here's the complete adapter class:
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private int mItemHeight = 0;
private int mNumColumns = 0;
private RelativeLayout.LayoutParams mImageViewLayoutParams;
public ImageAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mImageViewLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
}
public void setNumColumns(int numColumns) {
mNumColumns = numColumns;
}
public int getNumColumns() {
return mNumColumns;
}
public void setItemHeight(int height) {
if (height == mItemHeight) {
return;
}
mItemHeight = height;
mImageViewLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight);
// mImageFetcher.setImageSize(height);
notifyDataSetChanged();
}
public int getCount() {
return images.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ImageItem item = images.get(position);
holder.imageview.setId(position);
// holder.imageview.setImageBitmap(item.img);
holder.imageview.setLayoutParams(mImageViewLayoutParams);
// Check the height matches our calculated column width
if (holder.imageview.getLayoutParams().height != mItemHeight) {
holder.imageview.setLayoutParams(mImageViewLayoutParams);
}
holder.imageview.setImageBitmap(item.img);
holder.checkbox.setChecked(item.selection);
return convertView;
}
}