Процентная ширина в RelativeLayout

Если вы когда-либо выкапывали BCL, вы обнаружите, что способы поиска родительского процесса сознательно избегают, возьмите это, например:

https://referencesource.microsoft.com /#System/services/monitoring/system/diagnosticts/ProcessManager.cs,327

Как вы можете видеть в исходном коде, он содержит комплексные структуры и импортированные собственные методы, которые абсолютно достаточны для справиться с работой. Однако, даже если вы обращаетесь к ним через рефлексию (это возможно), вы не найдете метода для этого. Я не могу ответить, почему, но это явление вызывает несколько повторений таких вопросов, как ваша. например:

Как я могу получить PID родительского процесса моего приложения

Поскольку нет ответа вместе с некоторым кодом с помощью CreateToolhelp32Snapshot в этом потоке я бы добавил - часть определений структуры и имен, которые я ворую из исходного источника MS:)

  • Код
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Linq;
    using System;
    
    public static class Toolhelp32 {
        public const uint Inherit = 0x80000000;
        public const uint SnapModule32 = 0x00000010;
        public const uint SnapAll = SnapHeapList|SnapModule|SnapProcess|SnapThread;
        public const uint SnapHeapList = 0x00000001;
        public const uint SnapProcess = 0x00000002;
        public const uint SnapThread = 0x00000004;
        public const uint SnapModule = 0x00000008;
    
        [DllImport("kernel32.dll")]
        static extern bool CloseHandle(IntPtr handle);
        [DllImport("kernel32.dll")]
        static extern IntPtr CreateToolhelp32Snapshot(uint flags, int processId);
    
        public static IEnumerable TakeSnapshot(uint flags, int id) where T : IEntry, new() {
            using(var snap = new Snapshot(flags, id))
                for(IEntry entry = new T { }; entry.TryMoveNext(snap, out entry);)
                    yield return (T)entry;
        }
    
        public interface IEntry {
            bool TryMoveNext(Toolhelp32.Snapshot snap, out IEntry entry);
        }
    
        public struct Snapshot:IDisposable {
            void IDisposable.Dispose() {
                Toolhelp32.CloseHandle(m_handle);
            }
            public Snapshot(uint flags, int processId) {
                m_handle=Toolhelp32.CreateToolhelp32Snapshot(flags, processId);
            }
            IntPtr m_handle;
        }
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct WinProcessEntry:Toolhelp32.IEntry {
        [DllImport("kernel32.dll")]
        public static extern bool Process32Next(Toolhelp32.Snapshot snap, ref WinProcessEntry entry);
    
        public bool TryMoveNext(Toolhelp32.Snapshot snap, out Toolhelp32.IEntry entry) {
            var x = new WinProcessEntry { dwSize=Marshal.SizeOf(typeof(WinProcessEntry)) };
            var b = Process32Next(snap, ref x);
            entry=x;
            return b;
        }
    
        public int dwSize;
        public int cntUsage;
        public int th32ProcessID;
        public IntPtr th32DefaultHeapID;
        public int th32ModuleID;
        public int cntThreads;
        public int th32ParentProcessID;
        public int pcPriClassBase;
        public int dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public String fileName;
        //byte fileName[260];
        //public const int sizeofFileName = 260;
    }
    
    public static class Extensions {
        public static Process Parent(this Process p) {
            var entries = Toolhelp32.TakeSnapshot(Toolhelp32.SnapAll, 0);
            var parentid = entries.First(x => x.th32ProcessID==p.Id).th32ParentProcessID;
            return Process.GetProcessById(parentid);
        }
    }
    

И мы можем использовать его как:

  • Тест
    public class TestClass {
        public static void TestMethod() {
            var p = Process.GetCurrentProcess().Parent();
            Console.WriteLine("{0}", p.Id);
        }
    }
    

Для альтернативного окончания ..

Согласно документации, существует пара итерационных методов для каждого типа записей, таких как Process32First и Process32Next, для итерации процессов; но я обнаружил, что методы «xxxxFirst» не нужны, и тогда я подумал, почему бы не поместить метод итерации с соответствующим типом записи? Было бы проще реализовать и понять (я думаю, так ..).

Так же, как Toolhelp32, суффикс с помощью help , я считаю, что статический вспомогательный класс является правильным, так что мы можем иметь ясные квалифицированные имена, такие как Toolhelp32.Snapshot или Toolhelp32.IEntry хотя это было бы неуместно здесь.

Как только родительский процесс будет получен, если вы хотите получить подробную информацию, вы можете легко расширить его, например, итерации по своим модулям, а затем добавить :

  • Код - WinModuleEntry
    [StructLayout(LayoutKind.Sequential)]
    public struct WinModuleEntry:Toolhelp32.IEntry { // MODULEENTRY32
        [DllImport("kernel32.dll")]
        public static extern bool Module32Next(Toolhelp32.Snapshot snap, ref WinModuleEntry entry);
    
        public bool TryMoveNext(Toolhelp32.Snapshot snap, out Toolhelp32.IEntry entry) {
            var x = new WinModuleEntry { dwSize=Marshal.SizeOf(typeof(WinModuleEntry)) };
            var b = Module32Next(snap, ref x);
            entry=x;
            return b;
        }
    
        public int dwSize;
        public int th32ModuleID;
        public int th32ProcessID;
        public int GlblcntUsage;
        public int ProccntUsage;
        public IntPtr modBaseAddr;
        public int modBaseSize;
        public IntPtr hModule;
        //byte moduleName[256];
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string moduleName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string fileName;
        //byte fileName[260];
        //public const int sizeofModuleName = 256;
        //public const int sizeofFileName = 260;
    }
    
    и некоторый тест ..
    public class TestClass {
        public static void TestMethod() {
            var p = Process.GetCurrentProcess().Parent();
            Console.WriteLine("{0}", p.Id);
    
            var formatter = new CustomFormatter { };
            foreach(var x in Toolhelp32.TakeSnapshot(Toolhelp32.SnapModule, p.Id)) {
                Console.WriteLine(String.Format(formatter, "{0}", x));
            }
        }
    }
    
    public class CustomFormatter:IFormatProvider, ICustomFormatter {
        String ICustomFormatter.Format(String format, object arg, IFormatProvider formatProvider) {
            var type = arg.GetType();
            var fields = type.GetFields();
            var q = fields.Select(x => String.Format("{0}:{1}", x.Name, x.GetValue(arg)));
            return String.Format("{{{0}}}", String.Join(", ", q.ToArray()));
        }
    
        object IFormatProvider.GetFormat(Type formatType) {
            return typeof(ICustomFormatter)!=formatType ? null : this;
        }
    }
    

Если вам нужен пример кода ..

431
задан JasonMArcher 12 September 2015 в 17:03
поделиться

6 ответов

Просто поместите ваши два textview-хоста и порт в независимую горизонтальную линейную форму и используйте android: layout_weight, чтобы сделать процент

3
ответ дан Cyatophilum 12 September 2015 в 17:03
поделиться

Вы можете сделать это с помощью весов макета. Вес определяет, как разделить невостребованные части экрана. Дайте каждому EditText layout_width 0 и некоторый пропорциональный вес. То есть, дайте одному вес 2, а другому - 1, если вы хотите, чтобы первый занимал вдвое больше места.

3
ответ дан Cheryl Simon 12 September 2015 в 17:03
поделиться

Вы можете использовать PercentRelativeLayout . Это недавнее недокументированное дополнение к библиотеке поддержки проектирования , позволяющее задавать не только элементы относительно друг друга, но и общий процент доступного пространства.

Подкласс RelativeLayout, который поддерживает измерения и поля в процентах. Вы можете указать измерение или поле дочернего элемента, используя атрибуты с суффиксом «Процент».

<android.support.percent.PercentRelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
  <ImageView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_widthPercent="50%"
      app:layout_heightPercent="50%"
      app:layout_marginTopPercent="25%"
      app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentFrameLayout>

Пакет Percent предоставляет API-интерфейсы для поддержки добавления и управления измерениями на основе процента в вашем приложении.

Для использования вам необходимо добавить эту библиотеку в список зависимостей Gradle :

dependencies {
    compile 'com.android.support:percent:22.2.0'//23.1.1
}
18
ответ дан IntelliJ Amiya 12 September 2015 в 17:03
поделиться

Вы можете взглянуть на новую библиотеку поддержки процентов.

compile 'com.android.support:percent:22.2.0'

документы

выборка

31
ответ дан IntelliJ Amiya 12 September 2015 в 17:03
поделиться

Вы не можете использовать проценты для определения размеров представления внутри RelativeLayout. Лучший способ сделать это - использовать LinearLayout и веса или пользовательский макет.

78
ответ дан Romain Guy 12 September 2015 в 17:03
поделиться

Обновление 1

Как указано @EmJiHash PercentRelativeLayout устарело на уровне API 26.0.0

Ниже цитируется комментарий Google:

Этот класс устарел на уровне API 26.0.0. рассмотрите использование ConstraintLayout и связанных макетов вместо этого. Далее показано, как реплицировать функциональность процентных макетов с помощью ConstraintLayout


Google представила новый API под названием android.support.percent

Затем вы можете просто указать процентное соотношение для просмотра

Добавить зависимость компиляции, например,

compile 'com.android.support:percent:22.2.0

, в которой PercentRelativeLayout равно что мы можем сделать в процентном соотношении

 <android.support.percent.PercentRelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     <ImageView
         app:layout_widthPercent="50%"
         app:layout_heightPercent="50%"
         app:layout_marginTopPercent="25%"
         app:layout_marginLeftPercent="25%"/>
 </android.support.percent.PercentRelativeLayout>
132
ответ дан N J 12 September 2015 в 17:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: