All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.solovyev.android.Views Maven / Gradle / Ivy

There is a newer version: 1.1.18
Show newest version
/*
 * Copyright 2013 serso aka se.solovyev
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Contact details
 *
 * Email: [email protected]
 * Site:  http://se.solovyev.org
 */

package org.solovyev.android;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.*;
import android.widget.TabHost;
import android.widget.TextView;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * User: serso
 * Date: 2/2/13
 * Time: 5:57 PM
 */
public final class Views {

	private static final boolean AT_LEAST_API_5 = Build.VERSION.SDK_INT >= 5;

	private Views() {
		throw new AssertionError();
	}

	/**
	 * Method runs through view and all it's children recursively and process them via viewProcessor
	 *
	 * @param view          parent view to be processed, if view is ViewGroup then all it's children will be processed
	 * @param viewProcessor object which processes views
	 */
	public static void processViews(@Nonnull View view, @Nonnull ViewProcessor viewProcessor) {
		processViewsOfType0(view, null, viewProcessor);
	}

	static  void processViewsOfType0(@Nonnull View view, @Nullable Class viewClass, @Nonnull ViewProcessor viewProcessor) {
		if (view instanceof ViewGroup) {
			final ViewGroup viewGroup = (ViewGroup) view;

			if (viewClass == null || viewClass.isAssignableFrom(ViewGroup.class)) {
				//noinspection unchecked
				viewProcessor.process((T) viewGroup);
			}

			for (int index = 0; index < viewGroup.getChildCount(); index++) {
				processViewsOfType0(viewGroup.getChildAt(index), viewClass, viewProcessor);
			}
		} else if (viewClass == null || viewClass.isAssignableFrom(view.getClass())) {
			//noinspection unchecked
			viewProcessor.process((T) view);
		}
	}

	/**
	 * Method runs through view and all it's children recursively and process all instances of viewClass via viewProcessor
	 *
	 * @param view          parent view to be processed, if view is ViewGroup then all it's children will be processed
	 * @param viewClass     only instances of specified class will be processed
	 * @param viewProcessor object which processes views
	 */
	public static  void processViewsOfType(@Nonnull View view, @Nonnull Class viewClass, @Nonnull ViewProcessor viewProcessor) {
		processViewsOfType0(view, viewClass, viewProcessor);
	}

	/**
	 * Method center the tabs' contents on specified tabHost elements.
	 * This method should be invoked only for tabs with only text on them (and no image)
	 * This method checks some known devices/android versions/builds which don't support tab centering and do nothing for them
	 * 

* NOTE: be aware that this method doesn't cover all unsupported cases, for sure don't use this method * * @param tabHost tabHost element */ public static void centerAndWrapTabsFor(@Nonnull TabHost tabHost) { if (allowCenterAndWrappingTabs()) { int tabCount = tabHost.getTabWidget().getTabCount(); for (int i = 0; i < tabCount; i++) { final View view = tabHost.getTabWidget().getChildTabViewAt(i); if (view != null) { if (view.getLayoutParams().height > 0) { // reduce height of the tab view.getLayoutParams().height *= 0.8; } // get title text view final View textView = view.findViewById(android.R.id.title); if (textView instanceof TextView) { // just in case check the type // center text ((TextView) textView).setGravity(Gravity.CENTER); // wrap text ((TextView) textView).setSingleLine(false); // explicitly set layout parameters textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT; textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; } } } } } /** * Internal method where checking if device supports centering of text tabs * * @return true if centering of text tabs is supported for this device/build/OS version */ private static boolean allowCenterAndWrappingTabs() { boolean result = true; String deviceModel = Build.MODEL; if (deviceModel != null) { deviceModel = deviceModel.toUpperCase(); if (deviceModel.contains("M1") || deviceModel.contains("MIONE") || deviceModel.contains("MI-ONE")) { // Xiaomi Phone MiOne => do not allow to center and wrap tabs result = false; Log.i(Android.class.getName(), "Device model doesn't support center and wrap of tabs: " + Build.MODEL); } } if (result) { String buildId = Build.DISPLAY; if (buildId != null) { buildId = buildId.toUpperCase(); if (buildId.contains("MIUI")) { // fix for MIUI ROM result = false; Log.i(Android.class.getName(), "Device build doesn't support center and wrap of tabs: " + Build.DISPLAY); } } } return result; } /** * Method adds tab to the tabHost element * * @param context activity which users tabHost * @param tabHost tabHost element * @param tabId id of tab to be added * @param tabCaptionId string id of tab to be added * @param activityClass activity class to be invoked if the tab is pressed */ public static void addTab(@Nonnull Context context, @Nonnull TabHost tabHost, @Nonnull String tabId, int tabCaptionId, @Nonnull Class activityClass) { // create intent to be invoked on tab press final Intent intent = new Intent().setClass(context, activityClass); // init TabSpec final TabHost.TabSpec tabSpec = tabHost.newTabSpec(tabId).setIndicator(context.getString(tabCaptionId)).setContent(intent); tabHost.addTab(tabSpec); } public static int toPixels(@Nonnull DisplayMetrics dm, float dps) { final float scale = dm.density; return (int) (dps * scale + 0.5f); } public static int getScreenOrientation(@Nonnull Activity activity) { final Display display = activity.getWindowManager().getDefaultDisplay(); final int result; if (display.getWidth() <= display.getHeight()) { result = Configuration.ORIENTATION_PORTRAIT; } else { result = Configuration.ORIENTATION_LANDSCAPE; } return result; } // copied from API-15 public static boolean isLayoutSizeAtLeast(int size, @Nonnull Configuration configuration) { int cur = configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; if (cur == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) return false; return cur >= size; } public static int getPointerCountFromMotionEvent(@Nonnull MotionEvent event) { return AT_LEAST_API_5 ? event.getPointerCount() : 1; } public static float getXFromMotionEvent(@Nonnull MotionEvent event, int pointer) { return AT_LEAST_API_5 ? event.getX(pointer) : 0; } public static float getYFromMotionEvent(@Nonnull MotionEvent event, int pointer) { return AT_LEAST_API_5 ? event.getY(pointer) : 0; } /** * Interface to process view. See AndroidUtils#processViews(android.view.View, AndroidUtils.ViewProcessor) for more details * * @param view type * @see Views#processViews(android.view.View, ViewProcessor */ public static interface ViewProcessor { void process(@Nonnull V view); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy